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 | 5a5b38f4afaf4f203b96a11ba79890c7cd4cc4b8 (patch) | |
tree | 6eb8e5b2b7431d07020520ee0a88e85d7001cbf4 /lib/Sema/SemaChecking.cpp | |
parent | c29ea8fb903f9f7e3d8bdf8cb57b87eb3713826b (diff) |
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>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@127514 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaChecking.cpp')
-rw-r--r-- | lib/Sema/SemaChecking.cpp | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index 4cdbf5375e..ea14b4bbb1 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/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); } |