In getIntWidth we special case enums and boolean types, but this
handling can be defeated if the type is hidden inside an
ElaboratedType. Notably, scoped enum bools in a namespace that are
referred to by a fully qualified name skip past both checks.

This then causes an assert when something of that type is involved in an
implicit cast.

We can avoid this by explicitly stripping the elaborated type.

Okay to commit?

>From f97ff0a425a023d47ab55c6d24280064d215cae2 Mon Sep 17 00:00:00 2001
From: Justin Bogner <[email protected]>
Date: Wed, 9 Oct 2013 21:37:00 -0700
Subject: [PATCH] AST: Handle elaborated types in getIntWidth

In getIntWidth we special case enums and boolean types, but this
handling can be defeated if the type is hidden inside an
ElaboratedType. Notably, scoped enum bools in a namespace that are
referred to by a fully qualified name skip past both checks.

We can avoid this by explicitly stripping the elaborated type.

Fixes rdar://problem/15124329
---
 lib/AST/ASTContext.cpp       | 2 ++
 test/SemaCXX/enum-scoped.cpp | 9 +++++++++
 2 files changed, 11 insertions(+)

diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 3b5bfe6..3cef7ab 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -7463,6 +7463,8 @@ QualType ASTContext::mergeObjCGCQualifiers(QualType LHS, QualType RHS) {
 //===----------------------------------------------------------------------===//
 
 unsigned ASTContext::getIntWidth(QualType T) const {
+  if (const ElaboratedType *ET = dyn_cast<ElaboratedType>(T))
+    T = ET->getNamedType();
   if (const EnumType *ET = dyn_cast<EnumType>(T))
     T = ET->getDecl()->getIntegerType();
   if (T->isBooleanType())
diff --git a/test/SemaCXX/enum-scoped.cpp b/test/SemaCXX/enum-scoped.cpp
index a9a6de9..c901d8d 100644
--- a/test/SemaCXX/enum-scoped.cpp
+++ b/test/SemaCXX/enum-scoped.cpp
@@ -271,3 +271,12 @@ namespace PR16900 {
   enum class A;
   A f(A a) { return -a; } // expected-error {{invalid argument type 'PR16900::A' to unary expression}}
 }
+
+namespace rdar15124329 {
+  // Shouldn't crash
+  enum class B : bool { F, T };
+  bool implicitlyCastElaboratedType() {
+    const rdar15124329::B CT = B::T;
+    return CT == B::F;
+  }
+}
-- 
1.8.3.4 (Apple Git-47)

_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to