diff options
| author | Aaron Ballman <aaron@aaronballman.com> | 2016-09-02 13:45:40 +0000 |
|---|---|---|
| committer | Aaron Ballman <aaron@aaronballman.com> | 2016-09-02 13:45:40 +0000 |
| commit | ff7bd8bacd13019529b7709efa95ae834c4537a4 (patch) | |
| tree | ff511e9235c978455b7449545dbefa7a2d123ae0 /clang/lib | |
| parent | fd503e5af306b6aad3dd3d7005ff86e008aad2dd (diff) | |
| download | bcm5719-llvm-ff7bd8bacd13019529b7709efa95ae834c4537a4.tar.gz bcm5719-llvm-ff7bd8bacd13019529b7709efa95ae834c4537a4.zip | |
Allow a C11 generic selection expression to select a function with the overloadable attribute as the result expression without crashing. This fixes PR30201.
llvm-svn: 280483
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 72ad9a4d715..36643812b02 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -12984,6 +12984,31 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found, ICE->getValueKind()); } + if (auto *GSE = dyn_cast<GenericSelectionExpr>(E)) { + if (!GSE->isResultDependent()) { + Expr *SubExpr = + FixOverloadedFunctionReference(GSE->getResultExpr(), Found, Fn); + if (SubExpr == GSE->getResultExpr()) + return GSE; + + // Replace the resulting type information before rebuilding the generic + // selection expression. + SmallVector<Expr *, 4> AssocExprs(GSE->getAssocExprs().begin(), + GSE->getAssocExprs().end()); + unsigned ResultIdx = GSE->getResultIndex(); + AssocExprs[ResultIdx] = SubExpr; + + return new (Context) GenericSelectionExpr( + Context, GSE->getGenericLoc(), GSE->getControllingExpr(), + GSE->getAssocTypeSourceInfos(), AssocExprs, GSE->getDefaultLoc(), + GSE->getRParenLoc(), GSE->containsUnexpandedParameterPack(), + ResultIdx); + } + // Rather than fall through to the unreachable, return the original generic + // selection expression. + return GSE; + } + if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(E)) { assert(UnOp->getOpcode() == UO_AddrOf && "Can only take the address of an overloaded function"); |

