Issue diagnostic when constructor or destructor

return void expression. // rdar://15366494
pr17759.

llvm-svn: 196296
This commit is contained in:
Fariborz Jahanian 2013-12-03 17:10:08 +00:00
parent 46db725a43
commit a759848126
3 changed files with 28 additions and 4 deletions

View File

@ -6426,6 +6426,8 @@ def ext_return_has_void_expr : Extension<
def err_return_init_list : Error<
"%select{void function|void method|constructor|destructor}1 %0 "
"must not return a value">;
def err_ctor_dtor_returns_void : Error<
"%select{constructor|destructor}1 %0 must not return void expression">;
def warn_noreturn_function_has_return_expr : Warning<
"function %0 declared 'noreturn' should not return">,
InGroup<InvalidNoreturn>;

View File

@ -2801,8 +2801,14 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
} else if (!RetValExp->isTypeDependent()) {
// C99 6.8.6.4p1 (ext_ since GCC warns)
unsigned D = diag::ext_return_has_expr;
if (RetValExp->getType()->isVoidType())
if (RetValExp->getType()->isVoidType()) {
NamedDecl *CurDecl = getCurFunctionOrMethodDecl();
if (isa<CXXConstructorDecl>(CurDecl) ||
isa<CXXDestructorDecl>(CurDecl))
D = diag::err_ctor_dtor_returns_void;
else
D = diag::ext_return_has_void_expr;
}
else {
ExprResult Result = Owned(RetValExp);
Result = IgnoredValueConversions(Result.take());
@ -2812,9 +2818,15 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
RetValExp = ImpCastExprToType(RetValExp,
Context.VoidTy, CK_ToVoid).take();
}
// return of void in constructor/destructor is illegal in C++.
if (D == diag::err_ctor_dtor_returns_void) {
NamedDecl *CurDecl = getCurFunctionOrMethodDecl();
Diag(ReturnLoc, D)
<< CurDecl->getDeclName() << isa<CXXDestructorDecl>(CurDecl)
<< RetValExp->getSourceRange();
}
// return (some void expression); is legal in C++.
if (D != diag::ext_return_has_void_expr ||
else if (D != diag::ext_return_has_void_expr ||
!getLangOpts().CPlusPlus) {
NamedDecl *CurDecl = getCurFunctionOrMethodDecl();

View File

@ -102,3 +102,13 @@ namespace return_has_expr {
}
};
}
// rdar://15366494
// pr17759
namespace ctor_returns_void {
void f() {}
struct S {
S() { return f(); }; // expected-error {{constructor 'S' must not return void expression}}
~S() { return f(); } // expected-error {{destructor '~S' must not return void expression}}
};
}