diff options
| author | Fariborz Jahanian <fjahanian@apple.com> | 2013-12-03 17:10:08 +0000 |
|---|---|---|
| committer | Fariborz Jahanian <fjahanian@apple.com> | 2013-12-03 17:10:08 +0000 |
| commit | a759848126bac678918e4cb52a0beec25f2a04f5 (patch) | |
| tree | bb533a27ca82cbe4427a1bf236da482e1c85fc96 /clang/lib/Sema/SemaStmt.cpp | |
| parent | 46db725a43b66771499e1e89df2160a61d63dc31 (diff) | |
| download | bcm5719-llvm-a759848126bac678918e4cb52a0beec25f2a04f5.tar.gz bcm5719-llvm-a759848126bac678918e4cb52a0beec25f2a04f5.zip | |
Issue diagnostic when constructor or destructor
return void expression. // rdar://15366494
pr17759.
llvm-svn: 196296
Diffstat (limited to 'clang/lib/Sema/SemaStmt.cpp')
| -rw-r--r-- | clang/lib/Sema/SemaStmt.cpp | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 861d5cf240c..6bda42deaa2 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -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()) - D = diag::ext_return_has_void_expr; + 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(); |

