Index: lib/Sema/SemaCast.cpp =================================================================== --- lib/Sema/SemaCast.cpp +++ lib/Sema/SemaCast.cpp @@ -2173,7 +2173,38 @@ // So we finish by allowing everything that remains - it's got to be two // object pointers. return TC_Success; -} +} + +/// DiagnoseCastQual - Warn whenever casts discards a qualifiers, be it either +/// const, volatile or both. +static void DiagnoseCastQual(Sema &Self, const ExprResult &SrcExpr, + QualType DestType) { + // -Wcast-qual + QualType TheOffendingSrcType, TheOffendingDestType; + Qualifiers CastAwayQualifiers; + QualType SrcType = SrcExpr.get()->getType(); + if (!(SrcType->isAnyPointerType() && DestType->isAnyPointerType() && + CastsAwayConstness(Self, SrcType, DestType, true, false, + &TheOffendingSrcType, &TheOffendingDestType, + &CastAwayQualifiers))) + return; + + int qualifiers = -1; + if (CastAwayQualifiers.hasConst() && CastAwayQualifiers.hasVolatile()) { + qualifiers = 0; + } else if (CastAwayQualifiers.hasConst()) { + qualifiers = 1; + } else if (CastAwayQualifiers.hasVolatile()) { + qualifiers = 2; + } + // This is a variant of int **x; const int **y = (const int **)x; + if (qualifiers == -1) + Self.Diag(SrcExpr.get()->getLocStart(), diag::warn_cast_qual2) + << SrcType << DestType; + else + Self.Diag(SrcExpr.get()->getLocStart(), diag::warn_cast_qual) + << TheOffendingSrcType << TheOffendingDestType << qualifiers; +} void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle, bool ListInitialization) { @@ -2305,6 +2336,9 @@ // Clear out SrcExpr if there was a fatal error. if (tcr != TC_Success) SrcExpr = ExprError(); + + // -Wcast-qual + DiagnoseCastQual(Self, SrcExpr, DestType); } /// DiagnoseBadFunctionCast - Warn whenever a function call is cast to a @@ -2582,28 +2616,7 @@ checkCastAlign(); // -Wcast-qual - QualType TheOffendingSrcType, TheOffendingDestType; - Qualifiers CastAwayQualifiers; - if (SrcType->isAnyPointerType() && DestType->isAnyPointerType() && - CastsAwayConstness(Self, SrcType, DestType, true, false, - &TheOffendingSrcType, &TheOffendingDestType, - &CastAwayQualifiers)) { - int qualifiers = -1; - if (CastAwayQualifiers.hasConst() && CastAwayQualifiers.hasVolatile()) { - qualifiers = 0; - } else if (CastAwayQualifiers.hasConst()) { - qualifiers = 1; - } else if (CastAwayQualifiers.hasVolatile()) { - qualifiers = 2; - } - // This is a variant of int **x; const int **y = (const int **)x; - if (qualifiers == -1) - Self.Diag(SrcExpr.get()->getLocStart(), diag::warn_cast_qual2) << - SrcType << DestType; - else - Self.Diag(SrcExpr.get()->getLocStart(), diag::warn_cast_qual) << - TheOffendingSrcType << TheOffendingDestType << qualifiers; - } + DiagnoseCastQual(Self, SrcExpr, DestType); } ExprResult Sema::BuildCStyleCastExpr(SourceLocation LPLoc, Index: test/Sema/warn-cast-qual.c =================================================================== --- test/Sema/warn-cast-qual.c +++ test/Sema/warn-cast-qual.c @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -triple x86_64-unknown-unknown -fsyntax-only -Wcast-qual -verify %s +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -x c++ -fsyntax-only -Wcast-qual -verify %s #include @@ -26,4 +27,7 @@ const char **charptrptrc; char **charptrptr = (char **)charptrptrc; // expected-warning {{cast from 'const char *' to 'char *' drops const qualifier}} + + const char *constcharptr; + char *charptr = (char *)constcharptr; // expected-warning {{cast from 'const char *' to 'char *' drops const qualifier}} }