Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td (revision 196171) +++ include/clang/Basic/DiagnosticSemaKinds.td (working copy) @@ -6426,6 +6426,8 @@ 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; Index: lib/Sema/SemaStmt.cpp =================================================================== --- lib/Sema/SemaStmt.cpp (revision 196171) +++ lib/Sema/SemaStmt.cpp (working copy) @@ -2801,8 +2801,14 @@ } 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(CurDecl) || + isa(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 @@ 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(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(); Index: test/SemaCXX/return.cpp =================================================================== --- test/SemaCXX/return.cpp (revision 196171) +++ test/SemaCXX/return.cpp (working copy) @@ -102,3 +102,13 @@ } }; } + +// 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}} + }; +}