diff options
| author | Jordan Rose <jordan_rose@apple.com> | 2012-07-02 21:19:23 +0000 |
|---|---|---|
| committer | Jordan Rose <jordan_rose@apple.com> | 2012-07-02 21:19:23 +0000 |
| commit | d39e5f14636bec2ef3164c12d80fbd40ad36e88f (patch) | |
| tree | ece3c2b5fc5acc70cb80ea27d09ce3820061432e /clang/lib/Sema/SemaExpr.cpp | |
| parent | dd8638fb3e172da32e0ed3e30ac80535b40c054e (diff) | |
| download | bcm5719-llvm-d39e5f14636bec2ef3164c12d80fbd40ad36e88f.tar.gz bcm5719-llvm-d39e5f14636bec2ef3164c12d80fbd40ad36e88f.zip | |
In blocks, only pretend that enum constants have enum type if necessary.
In C, enum constants have the type of the enum's underlying integer type,
rather than the type of the enum. (This is not true in C++.) Thus, when a
block's return type is inferred from an enum constant, it is incompatible
with expressions that return the enum type.
In r158899, I told block returns to pretend that enum constants have enum
type, like in C++. Doug Gregor pointed out that this can break existing code.
Now, we don't check the types of return statements until the end of the block.
This lets us go back and add implicit casts in blocks with mixed enum
constants and enum-typed expressions.
<rdar://problem/11662489> (again)
llvm-svn: 159591
Diffstat (limited to 'clang/lib/Sema/SemaExpr.cpp')
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index e65c21d085b..1f2850f6ecb 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -9350,7 +9350,10 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, PopExpressionEvaluationContext(); BlockScopeInfo *BSI = cast<BlockScopeInfo>(FunctionScopes.back()); - + + if (BSI->HasImplicitReturnType) + deduceClosureReturnType(*BSI); + PopDeclContext(); QualType RetTy = Context.VoidTy; @@ -9423,7 +9426,12 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, BSI->TheDecl->setBody(cast<CompoundStmt>(Body)); - computeNRVO(Body, getCurBlock()); + // Try to apply the named return value optimization. We have to check again + // if we can do this, though, because blocks keep return statements around + // to deduce an implicit return type. + if (getLangOpts().CPlusPlus && RetTy->isRecordType() && + !BSI->TheDecl->isDependentContext()) + computeNRVO(Body, getCurBlock()); BlockExpr *Result = new (Context) BlockExpr(BSI->TheDecl, BlockTy); const AnalysisBasedWarnings::Policy &WP = AnalysisWarnings.getDefaultPolicy(); |

