[cfe-commits] r127514 - in /cfe/trunk: lib/Sema/SemaChecking.cpp test/Sema/conversion.c
Douglas Gregor
dgregor at apple.com
Fri Mar 11 16:14:31 PST 2011
Author: dgregor
Date: Fri Mar 11 18:14:31 2011
New Revision: 127514
URL: http://llvm.org/viewvc/llvm-project?rev=127514&view=rev
Log:
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>.
Modified:
cfe/trunk/lib/Sema/SemaChecking.cpp
cfe/trunk/test/Sema/conversion.c
Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=127514&r1=127513&r2=127514&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Fri Mar 11 18:14:31 2011
@@ -2753,6 +2753,13 @@
<< 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 @@
}
// 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 @@
if (isFromSystemMacro(S, CC))
return;
- return DiagnoseImpCast(S, E, T, CC,
+ return DiagnoseImpCast(S, E, SourceType, T, CC,
diag::warn_impcast_different_enum_types);
}
Modified: cfe/trunk/test/Sema/conversion.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/conversion.c?rev=127514&r1=127513&r2=127514&view=diff
==============================================================================
--- cfe/trunk/test/Sema/conversion.c (original)
+++ cfe/trunk/test/Sema/conversion.c Fri Mar 11 18:14:31 2011
@@ -323,6 +323,10 @@
enum E8559831a a1 = value_a; // expected-warning{{implicit conversion from enumeration type 'enum E8559831b' to different enumeration type 'enum E8559831a'}}
a1 = value_a; // expected-warning{{implicit conversion from enumeration type 'enum E8559831b' to different enumeration type 'enum E8559831a'}}
+ test_8559831_a(E8559831b_val); // expected-warning{{implicit conversion from enumeration type 'enum E8559831b' to different enumeration type 'enum E8559831a'}}
+ enum E8559831a a1a = E8559831b_val; // expected-warning{{implicit conversion from enumeration type 'enum E8559831b' to different enumeration type 'enum E8559831a'}}
+ a1 = E8559831b_val; // expected-warning{{implicit conversion from enumeration type 'enum E8559831b' to different enumeration type 'enum E8559831a'}}
+
test_8559831_a(value_c); // expected-warning{{implicit conversion from enumeration type 'E8559831c' to different enumeration type 'enum E8559831a'}}
enum E8559831a a2 = value_c; // expected-warning{{implicit conversion from enumeration type 'E8559831c' to different enumeration type 'enum E8559831a'}}
a2 = value_c; // expected-warning{{implicit conversion from enumeration type 'E8559831c' to different enumeration type 'enum E8559831a'}}
More information about the cfe-commits
mailing list