aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2009-05-15 00:48:27 +0000
committerAnders Carlsson <andersca@mac.com>2009-05-15 00:48:27 +0000
commit03d77760a5db7990724b6901cea958a673ce0b39 (patch)
tree7d52643d5b2c315e88c58ffd6377ca2597595552
parentfd0e628aa8a1e3932445559cb1d950fee11ea9a9 (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.cpp2
-rw-r--r--lib/Sema/SemaTemplateInstantiateExpr.cpp14
-rw-r--r--test/SemaTemplate/instantiate-function-1.cpp13
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}}