aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaCast.cpp
diff options
context:
space:
mode:
authorDavid Blaikie <dblaikie@gmail.com>2012-10-16 18:53:14 +0000
committerDavid Blaikie <dblaikie@gmail.com>2012-10-16 18:53:14 +0000
commit9b29f4fe3d0600edf6ba00d48f2d4f2b1984f247 (patch)
treef13f077dad332226274079842e93f7628071be8d /lib/Sema/SemaCast.cpp
parent4695f91f4302a90ae462cd64dda59b34c3dad821 (diff)
Implement GCC's -Wint-to-pointer-cast.
This implementation doesn't warn on anything that GCC doesn't warn on with the exception of templates specializations (GCC doesn't warn, Clang does). The specific skipped cases (boolean, constant expressions, enums) are open for debate/adjustment if anyone wants to demonstrate that GCC is being overly conservative here. The only really obvious false positive I found was in the Clang regression suite's MPI test - apparently MPI uses specific flag values in pointer constants. (eg: #define FOO (void*)~0) git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@166039 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaCast.cpp')
-rw-r--r--lib/Sema/SemaCast.cpp20
1 files changed, 20 insertions, 0 deletions
diff --git a/lib/Sema/SemaCast.cpp b/lib/Sema/SemaCast.cpp
index 0c3757821e..bf25c61785 100644
--- a/lib/Sema/SemaCast.cpp
+++ b/lib/Sema/SemaCast.cpp
@@ -1491,6 +1491,22 @@ static void DiagnoseCastOfObjCSEL(Sema &Self, const ExprResult &SrcExpr,
}
}
+static void checkIntToPointerCast(bool CStyle, SourceLocation Loc,
+ const Expr *SrcExpr, QualType DestType,
+ Sema &Self) {
+ QualType SrcType = SrcExpr->getType();
+
+ // Not warning on reinterpret_cast, boolean, constant expressions, etc
+ // are not explicit design choices, but consistent with GCC's behavior.
+ // Feel free to modify them if you've reason/evidence for an alternative.
+ if (CStyle && SrcType->isIntegralType(Self.Context)
+ && !SrcType->isBooleanType()
+ && !SrcType->isEnumeralType()
+ && !SrcExpr->isIntegerConstantExpr(Self.Context)
+ && Self.Context.getTypeSize(DestType) > Self.Context.getTypeSize(SrcType))
+ Self.Diag(Loc, diag::warn_int_to_pointer_cast) << SrcType << DestType;
+}
+
static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr,
QualType DestType, bool CStyle,
const SourceRange &OpRange,
@@ -1689,6 +1705,8 @@ static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr,
if (SrcType->isIntegralOrEnumerationType()) {
assert(destIsPtr && "One type must be a pointer");
+ checkIntToPointerCast(CStyle, OpRange.getBegin(), SrcExpr.get(), DestType,
+ Self);
// C++ 5.2.10p5: A value of integral or enumeration type can be explicitly
// converted to a pointer.
// C++ 5.2.10p9: [Note: ...a null pointer constant of integral type is not
@@ -2071,6 +2089,8 @@ void CastOperation::CheckCStyleCast() {
SrcExpr = ExprError();
return;
}
+ checkIntToPointerCast(/* CStyle */ true, OpRange.getBegin(), SrcExpr.get(),
+ DestType, Self);
} else if (!SrcType->isArithmeticType()) {
if (!DestType->isIntegralType(Self.Context) &&
DestType->isArithmeticType()) {