r280483 - Allow a C11 generic selection expression to select a function with the overloadable attribute as the result expression without crashing. This fixes PR30201.

Aaron Ballman via cfe-commits cfe-commits at lists.llvm.org
Fri Sep 2 06:45:41 PDT 2016


Author: aaronballman
Date: Fri Sep  2 08:45:40 2016
New Revision: 280483

URL: http://llvm.org/viewvc/llvm-project?rev=280483&view=rev
Log:
Allow a C11 generic selection expression to select a function with the overloadable attribute as the result expression without crashing. This fixes PR30201.

Modified:
    cfe/trunk/include/clang/AST/Expr.h
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/test/Sema/generic-selection.c

Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=280483&r1=280482&r2=280483&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Fri Sep  2 08:45:40 2016
@@ -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))

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=280483&r1=280482&r2=280483&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Fri Sep  2 08:45:40 2016
@@ -12984,6 +12984,31 @@ Expr *Sema::FixOverloadedFunctionReferen
                                     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");

Modified: cfe/trunk/test/Sema/generic-selection.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/generic-selection.c?rev=280483&r1=280482&r2=280483&view=diff
==============================================================================
--- cfe/trunk/test/Sema/generic-selection.c (original)
+++ cfe/trunk/test/Sema/generic-selection.c Fri Sep  2 08:45:40 2016
@@ -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);
+}




More information about the cfe-commits mailing list