[PATCH] D61023: Fix crash on switch conditions of non-integer types in templates

Elizabeth Andrews via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Apr 23 08:36:31 PDT 2019


eandrews created this revision.
eandrews added reviewers: rnk, erichkeane.

Clang currently crashes for switch statements inside a template when the condition is non-integer and instantiation dependent. This is because contextual implicit conversion is skipped while acting on switch condition but this conversion is checked in an assert when acting on case statement.

This patch delays checks for dependent expressions till instantiation. Behavior now matches GCC.

Patch fixes Bug 40982.


https://reviews.llvm.org/D61023

Files:
  lib/Sema/SemaStmt.cpp
  test/SemaTemplate/non-integral-switch-cond.cpp


Index: test/SemaTemplate/non-integral-switch-cond.cpp
===================================================================
--- /dev/null
+++ test/SemaTemplate/non-integral-switch-cond.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct NOT_AN_INTEGRAL_TYPE {};
+
+template <typename T>
+struct foo {
+  NOT_AN_INTEGRAL_TYPE Bad;
+  void run() {
+    switch (Bad) { // expected-error {{statement requires expression of integer type ('NOT_AN_INTEGRAL_TYPE' invalid)}}
+    case 0:
+      break;
+    }
+  }
+};
+
+int main() {
+  foo<int> instance;
+  instance.run(); // expected-note {{in instantiation of member function 'foo<int>::run' requested here}}
+}
Index: lib/Sema/SemaStmt.cpp
===================================================================
--- lib/Sema/SemaStmt.cpp
+++ lib/Sema/SemaStmt.cpp
@@ -404,7 +404,8 @@
     QualType CondType = CondExpr->getType();
 
     auto CheckAndFinish = [&](Expr *E) {
-      if (CondType->isDependentType() || E->isTypeDependent())
+      if (CondType->isDependentType() || CondExpr->isInstantiationDependent() ||
+          E->isTypeDependent())
         return ExprResult(E);
 
       if (getLangOpts().CPlusPlus11) {
@@ -695,7 +696,8 @@
   Expr *CondExpr = Cond.get().second;
   assert((Cond.isInvalid() || CondExpr) && "switch with no condition");
 
-  if (CondExpr && !CondExpr->isTypeDependent()) {
+  if (CondExpr && !CondExpr->isTypeDependent() &&
+      !CondExpr->isInstantiationDependent()) {
     // We have already converted the expression to an integral or enumeration
     // type, when we parsed the switch condition. If we don't have an
     // appropriate type now, enter the switch scope but remember that it's


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D61023.196252.patch
Type: text/x-patch
Size: 1701 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20190423/72c1c7d9/attachment.bin>


More information about the cfe-commits mailing list