diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-08-14 20:16:31 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-08-14 20:16:31 +0000 |
commit | c58f38f2207292533b4b0fe44ec176bae10dc6ec (patch) | |
tree | 999ebdabc22a473cb5503025f8743066da61a01d /clang/lib/Sema/SemaStmt.cpp | |
parent | dbd65779649eb0a12e63c84c7f9d2cf9d3411a46 (diff) | |
download | bcm5719-llvm-c58f38f2207292533b4b0fe44ec176bae10dc6ec.tar.gz bcm5719-llvm-c58f38f2207292533b4b0fe44ec176bae10dc6ec.zip |
PR16875: The return type of a dependent function type is visible when it's
referenced as a member of the current instantiation. In that case, deduce the
type of the function to a dependent type rather than exposing an undeduced auto
type to the rest of the current instantiation.
The standard doesn't really say that the type is dependent in this case; I'll
bring this up with CWG.
llvm-svn: 188410
Diffstat (limited to 'clang/lib/Sema/SemaStmt.cpp')
-rw-r--r-- | clang/lib/Sema/SemaStmt.cpp | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 46e350bfa28..87e7e03b847 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -2611,7 +2611,21 @@ bool Sema::DeduceFunctionTypeFromReturnExpr(FunctionDecl *FD, IgnoreParens().castAs<FunctionProtoTypeLoc>().getResultLoc(); QualType Deduced; - if (RetExpr) { + if (RetExpr && isa<InitListExpr>(RetExpr)) { + // If the deduction is for a return statement and the initializer is + // a braced-init-list, the program is ill-formed. + Diag(RetExpr->getExprLoc(), diag::err_auto_fn_return_init_list); + return true; + } + + if (FD->isDependentContext()) { + // C++1y [dcl.spec.auto]p12: + // Return type deduction [...] occurs when the definition is + // instantiated even if the function body contains a return + // statement with a non-type-dependent operand. + assert(AT->isDeduced() && "should have deduced to dependent type"); + return false; + } else if (RetExpr) { // If the deduction is for a return statement and the initializer is // a braced-init-list, the program is ill-formed. if (isa<InitListExpr>(RetExpr)) { @@ -2652,7 +2666,8 @@ bool Sema::DeduceFunctionTypeFromReturnExpr(FunctionDecl *FD, // the program is ill-formed. if (AT->isDeduced() && !FD->isInvalidDecl()) { AutoType *NewAT = Deduced->getContainedAutoType(); - if (!Context.hasSameType(AT->getDeducedType(), NewAT->getDeducedType())) { + if (!FD->isDependentContext() && + !Context.hasSameType(AT->getDeducedType(), NewAT->getDeducedType())) { Diag(ReturnLoc, diag::err_auto_fn_different_deductions) << (AT->isDecltypeAuto() ? 1 : 0) << NewAT->getDeducedType() << AT->getDeducedType(); @@ -2696,13 +2711,10 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { // FIXME: Add a flag to the ScopeInfo to indicate whether we're performing // deduction. - bool HasDependentReturnType = FnRetType->isDependentType(); if (getLangOpts().CPlusPlus1y) { if (AutoType *AT = FnRetType->getContainedAutoType()) { FunctionDecl *FD = cast<FunctionDecl>(CurContext); - if (CurContext->isDependentContext()) - HasDependentReturnType = true; - else if (DeduceFunctionTypeFromReturnExpr(FD, ReturnLoc, RetValExp, AT)) { + if (DeduceFunctionTypeFromReturnExpr(FD, ReturnLoc, RetValExp, AT)) { FD->setInvalidDecl(); return StmtError(); } else { @@ -2711,6 +2723,8 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { } } + bool HasDependentReturnType = FnRetType->isDependentType(); + ReturnStmt *Result = 0; if (FnRetType->isVoidType()) { if (RetValExp) { |