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
