]> granicus.if.org Git - clang/commitdiff
Instantiate return statements.
authorAnders Carlsson <andersca@mac.com>
Fri, 15 May 2009 00:48:27 +0000 (00:48 +0000)
committerAnders Carlsson <andersca@mac.com>
Fri, 15 May 2009 00:48:27 +0000 (00:48 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71825 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaStmt.cpp
lib/Sema/SemaTemplateInstantiateExpr.cpp
test/SemaTemplate/instantiate-function-1.cpp

index 0c181ecf0135d36f46e1e04da5fceaab2595b4e3..e200c46e4f5354de03300f6617a9780fb578848b 100644 (file)
@@ -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;
index 50d5d4442f169134b780d3337c41d598f08c1af0..401075da3f789fc08620b5cdd3808b607c6b1751 100644 (file)
@@ -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
index 5ca34019480539bc0a3e129a8b57116de68be255..fd79902fdc92fe792f47c10da8fd4dd1b095a826 100644 (file)
@@ -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}}