Index: include/clang/AST/Expr.h =================================================================== --- include/clang/AST/Expr.h +++ include/clang/AST/Expr.h @@ -4447,11 +4447,19 @@ return cast(SubExprs[END_EXPR+i]); } Expr *getAssocExpr(unsigned i) { return cast(SubExprs[END_EXPR+i]); } - + ArrayRef getAssocExprs() const { + return NumAssocs + ? llvm::makeArrayRef( + &reinterpret_cast(SubExprs)[END_EXPR], NumAssocs) + : None; + } const TypeSourceInfo *getAssocTypeSourceInfo(unsigned i) const { return AssocTypes[i]; } TypeSourceInfo *getAssocTypeSourceInfo(unsigned i) { return AssocTypes[i]; } + ArrayRef getAssocTypeSourceInfos() const { + return NumAssocs ? llvm::makeArrayRef(&AssocTypes[0], NumAssocs) : None; + } QualType getAssocType(unsigned i) const { if (const TypeSourceInfo *TS = getAssocTypeSourceInfo(i)) Index: lib/Sema/SemaOverload.cpp =================================================================== --- lib/Sema/SemaOverload.cpp +++ lib/Sema/SemaOverload.cpp @@ -12984,6 +12984,30 @@ ICE->getValueKind()); } + if (auto *GSE = dyn_cast(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. + std::vector AssocExprs(GSE->getAssocExprs().vec()); + 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(E)) { assert(UnOp->getOpcode() == UO_AddrOf && "Can only take the address of an overloaded function"); Index: test/Sema/generic-selection.c =================================================================== --- test/Sema/generic-selection.c +++ test/Sema/generic-selection.c @@ -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 @@ // 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); +}