diff options
author | Anders Carlsson <andersca@mac.com> | 2009-05-15 00:48:27 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2009-05-15 00:48:27 +0000 |
commit | 03d77760a5db7990724b6901cea958a673ce0b39 (patch) | |
tree | 7d52643d5b2c315e88c58ffd6377ca2597595552 | |
parent | fd0e628aa8a1e3932445559cb1d950fee11ea9a9 (diff) |
Instantiate return statements.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71825 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateExpr.cpp | 14 | ||||
-rw-r--r-- | test/SemaTemplate/instantiate-function-1.cpp | 13 |
3 files changed, 28 insertions, 1 deletions
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 0c181ecf01..e200c46e4f 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -823,7 +823,7 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, ExprArg rex) { return Owned(new (Context) ReturnStmt(ReturnLoc, RetValExp)); } - if (!RetValExp) { + if (!RetValExp && !FnRetType->isDependentType()) { unsigned DiagID = diag::warn_return_missing_expr; // C90 6.6.6.4p4 // C99 6.8.6.4p1 (ext_ since GCC warns) if (getLangOptions().C99) DiagID = diag::ext_return_missing_expr; diff --git a/lib/Sema/SemaTemplateInstantiateExpr.cpp b/lib/Sema/SemaTemplateInstantiateExpr.cpp index 50d5d4442f..401075da3f 100644 --- a/lib/Sema/SemaTemplateInstantiateExpr.cpp +++ b/lib/Sema/SemaTemplateInstantiateExpr.cpp @@ -447,6 +447,7 @@ namespace { OwningStmtResult VisitExpr(Expr *E); OwningStmtResult VisitLabelStmt(LabelStmt *S); OwningStmtResult VisitGotoStmt(GotoStmt *S); + OwningStmtResult VisitReturnStmt(ReturnStmt *S); // Base case. I'm supposed to ignore this. OwningStmtResult VisitStmt(Stmt *S) { @@ -499,6 +500,19 @@ Sema::OwningStmtResult TemplateStmtInstantiator::VisitGotoStmt(GotoStmt *S) { S->getLabel()->getID()); } +Sema::OwningStmtResult +TemplateStmtInstantiator::VisitReturnStmt(ReturnStmt *S) { + Sema::OwningExprResult Result = SemaRef.ExprEmpty(); + if (Expr *E = S->getRetValue()) { + Result = SemaRef.InstantiateExpr(E, TemplateArgs); + + if (Result.isInvalid()) + return SemaRef.StmtError(); + } + + return SemaRef.ActOnReturnStmt(S->getReturnLoc(), move(Result)); +} + Sema::OwningStmtResult TemplateStmtInstantiator::VisitCompoundStmt(CompoundStmt *S) { // FIXME: We need an *easy* RAII way to delete these statements if diff --git a/test/SemaTemplate/instantiate-function-1.cpp b/test/SemaTemplate/instantiate-function-1.cpp index 5ca3401948..fd79902fdc 100644 --- a/test/SemaTemplate/instantiate-function-1.cpp +++ b/test/SemaTemplate/instantiate-function-1.cpp @@ -37,3 +37,16 @@ struct X3 { }; template struct X3<int>; + +template <typename T> struct X4 { + T f() const { + return; // expected-warning{{non-void function 'f' should return a value}} + } + + T g() const { + return 1; // expected-warning{{void function 'g' should not return a value}} + } +}; + +template struct X4<void>; // expected-note{{in instantiation of template class 'X4<void>' requested here}} +template struct X4<int>; // expected-note{{in instantiation of template class 'X4<int>' requested here}} |