summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaChecking.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-03-12 00:14:31 +0000
committerDouglas Gregor <dgregor@apple.com>2011-03-12 00:14:31 +0000
commit364f7db0636ae535cb1e9a59cad45b3b102b828d (patch)
treec1954287f8b531ffdc80c8fed873a9dfb793320a /clang/lib/Sema/SemaChecking.cpp
parent30a87e38d904a24f8b7d5c5d9cf2ba4491cdb72b (diff)
downloadbcm5719-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.cpp21
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);
}
OpenPOWER on IntegriCloud