]> granicus.if.org Git - clang/commitdiff
Prevent Scoped Enums from being Integral constant expressions:
authorErich Keane <erich.keane@intel.com>
Fri, 20 Jul 2018 17:42:09 +0000 (17:42 +0000)
committerErich Keane <erich.keane@intel.com>
Fri, 20 Jul 2018 17:42:09 +0000 (17:42 +0000)
Discovered because of: https://bugs.llvm.org/show_bug.cgi?id=38235

It seems to me that a scoped enum should NOT be an integral constant expression
without a cast, so this seems like a sensical change.

Attributes that check for an integer parameter simply use this function to
ensure that they have an integer, so it was previously allowing a scoped enum.

Also added a test based on Richard's feedback to ensure that case labels still work.

Differential Revision: https://reviews.llvm.org/D49599

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@337585 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/ExprConstant.cpp
test/SemaCXX/PR38235.cpp [new file with mode: 0644]

index bf21bc65e2bf3d1453bda60fee0d74c1be09d281..e69914f25da2bb153a597df19f8830e761bf3801 100644 (file)
@@ -11142,7 +11142,7 @@ static bool EvaluateCPlusPlus11IntegralConstantExpr(const ASTContext &Ctx,
                                                     const Expr *E,
                                                     llvm::APSInt *Value,
                                                     SourceLocation *Loc) {
-  if (!E->getType()->isIntegralOrEnumerationType()) {
+  if (!E->getType()->isIntegralOrUnscopedEnumerationType()) {
     if (Loc) *Loc = E->getExprLoc();
     return false;
   }
diff --git a/test/SemaCXX/PR38235.cpp b/test/SemaCXX/PR38235.cpp
new file mode 100644 (file)
index 0000000..11874c8
--- /dev/null
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+enum class E { Foo, Bar = 97119 };
+
+void f() __attribute__((constructor(E::Foo))); // expected-error{{'constructor' attribute requires an integer constant}}
+void f2() __attribute__((constructor(E::Bar)));// expected-error{{'constructor' attribute requires an integer constant}}
+
+void switch_me(E e) {
+  switch (e) {
+    case E::Foo:
+    case E::Bar:
+      break;
+  }
+}