diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-03-12 00:14:31 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-03-12 00:14:31 +0000 |
commit | 364f7db0636ae535cb1e9a59cad45b3b102b828d (patch) | |
tree | c1954287f8b531ffdc80c8fed873a9dfb793320a /clang/lib/Sema/SemaChecking.cpp | |
parent | 30a87e38d904a24f8b7d5c5d9cf2ba4491cdb72b (diff) | |
download | bcm5719-llvm-364f7db0636ae535cb1e9a59cad45b3b102b828d.tar.gz bcm5719-llvm-364f7db0636ae535cb1e9a59cad45b3b102b828d.zip |
When we're determining whether to complain about a conversion from one
enumeration type to another in C, classify enumeration constants as if
they had the type of their enclosing enumeration. Fixes
<rdar://problem/9116337>.
llvm-svn: 127514
Diffstat (limited to 'clang/lib/Sema/SemaChecking.cpp')
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 4cdbf5375e6..ea14b4bbb1e 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -2753,6 +2753,13 @@ void DiagnoseImpCast(Sema &S, Expr *E, QualType T, SourceLocation CContext, << E->getType() << T << E->getSourceRange() << SourceRange(CContext); } +/// Diagnose an implicit cast; purely a helper for CheckImplicitConversion. +void DiagnoseImpCast(Sema &S, Expr *E, QualType SourceType, QualType T, + SourceLocation CContext, unsigned diag) { + S.Diag(E->getExprLoc(), diag) + << SourceType << T << E->getSourceRange() << SourceRange(CContext); +} + std::string PrettyPrintInRange(const llvm::APSInt &Value, IntRange Range) { if (!Range.Width) return "0"; @@ -2917,6 +2924,18 @@ void CheckImplicitConversion(Sema &S, Expr *E, QualType T, } // Diagnose conversions between different enumeration types. + // In C, we pretend that the type of an EnumConstantDecl is its enumeration + // type, to give us better diagnostics. + QualType SourceType = E->getType(); + if (!S.getLangOptions().CPlusPlus) { + if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) + if (EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(DRE->getDecl())) { + EnumDecl *Enum = cast<EnumDecl>(ECD->getDeclContext()); + SourceType = S.Context.getTypeDeclType(Enum); + Source = S.Context.getCanonicalType(SourceType).getTypePtr(); + } + } + if (const EnumType *SourceEnum = Source->getAs<EnumType>()) if (const EnumType *TargetEnum = Target->getAs<EnumType>()) if ((SourceEnum->getDecl()->getIdentifier() || @@ -2927,7 +2946,7 @@ void CheckImplicitConversion(Sema &S, Expr *E, QualType T, if (isFromSystemMacro(S, CC)) return; - return DiagnoseImpCast(S, E, T, CC, + return DiagnoseImpCast(S, E, SourceType, T, CC, diag::warn_impcast_different_enum_types); } |