Issue diagnostic when constructor or destructor
return void expression. // rdar://15366494 pr17759. llvm-svn: 196296
This commit is contained in:
parent
46db725a43
commit
a759848126
|
@ -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>;
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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}}
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue