forked from OSchip/llvm-project
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
This commit is contained in:
parent
fd503e5af3
commit
ff7bd8bacd
|
@ -4447,11 +4447,19 @@ public:
|
|||
return cast<Expr>(SubExprs[END_EXPR+i]);
|
||||
}
|
||||
Expr *getAssocExpr(unsigned i) { return cast<Expr>(SubExprs[END_EXPR+i]); }
|
||||
|
||||
ArrayRef<Expr *> getAssocExprs() const {
|
||||
return NumAssocs
|
||||
? llvm::makeArrayRef(
|
||||
&reinterpret_cast<Expr **>(SubExprs)[END_EXPR], NumAssocs)
|
||||
: None;
|
||||
}
|
||||
const TypeSourceInfo *getAssocTypeSourceInfo(unsigned i) const {
|
||||
return AssocTypes[i];
|
||||
}
|
||||
TypeSourceInfo *getAssocTypeSourceInfo(unsigned i) { return AssocTypes[i]; }
|
||||
ArrayRef<TypeSourceInfo *> getAssocTypeSourceInfos() const {
|
||||
return NumAssocs ? llvm::makeArrayRef(&AssocTypes[0], NumAssocs) : None;
|
||||
}
|
||||
|
||||
QualType getAssocType(unsigned i) const {
|
||||
if (const TypeSourceInfo *TS = getAssocTypeSourceInfo(i))
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// RUN: %clang_cc1 -std=c1x -fsyntax-only -verify %s
|
||||
// RUN: %clang_cc1 -std=c11 -fsyntax-only -verify %s
|
||||
|
||||
void g(void);
|
||||
|
||||
|
@ -36,3 +36,11 @@ void foo(int n) {
|
|||
// expression is not evaluated.
|
||||
(void)_Generic(*(int *)0, int: 1);
|
||||
}
|
||||
|
||||
int __attribute__((overloadable)) test (int);
|
||||
double __attribute__((overloadable)) test (double);
|
||||
char testc(char);
|
||||
|
||||
void PR30201(void) {
|
||||
_Generic(4, char:testc, default:test)(4);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue