From 41826bb59d2ef5e8c8a4a0cd2b06a7a011b67b4d Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Fri, 1 May 2009 02:23:58 +0000 Subject: [PATCH] PR4013 and PR4105: pointer-like types can only be cast to/from integers and other pointer-like types. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70531 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticSemaKinds.td | 4 ++++ lib/Sema/SemaExpr.cpp | 11 +++++++++++ test/Sema/cast.c | 6 ++++++ test/Sema/static-init.c | 2 +- 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index a416e52fcb..6bd5dec7dc 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -1319,6 +1319,10 @@ def ext_typecheck_cast_nonscalar : Extension< def ext_typecheck_cast_to_union : Extension<"C99 forbids casts to union type">; def err_typecheck_cast_to_union_no_type : Error< "cast to union type from type %0 not present in union">; +def err_cast_pointer_from_non_pointer_int : Error< + "operand of type %0 cannot be cast to a pointer type">; +def err_cast_pointer_to_non_pointer_int : Error< + "pointer cannot be cast to type %0">; def err_typecheck_expect_scalar_operand : Error< "operand of type %0 where arithmetic or pointer type is required">; def err_typecheck_cond_incompatible_operands : Error< diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 2de1ef300e..66b4c9c6b2 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -2604,6 +2604,17 @@ bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr) { return true; } else if (getLangOptions().ObjC1 && isa(castExpr)) { return Diag(castExpr->getLocStart(), diag::err_illegal_super_cast) << TyR; + } else if (!castType->isArithmeticType()) { + QualType castExprType = castExpr->getType(); + if (!castExprType->isIntegralType() && castExprType->isArithmeticType()) + return Diag(castExpr->getLocStart(), + diag::err_cast_pointer_from_non_pointer_int) + << castExprType << castExpr->getSourceRange(); + } else if (!castExpr->getType()->isArithmeticType()) { + if (!castType->isIntegralType() && castType->isArithmeticType()) + return Diag(castExpr->getLocStart(), + diag::err_cast_pointer_to_non_pointer_int) + << castType << castExpr->getSourceRange(); } return false; } diff --git a/test/Sema/cast.c b/test/Sema/cast.c index 6ceec6923c..ec19626d28 100644 --- a/test/Sema/cast.c +++ b/test/Sema/cast.c @@ -5,4 +5,10 @@ cpumask_t x; void foo() { (void)x; } +void bar() { + char* a; + double b; + b = (double)a; // expected-error {{pointer cannot be cast to type}} + a = (char*)b; // expected-error {{cannot be cast to a pointer type}} +} diff --git a/test/Sema/static-init.c b/test/Sema/static-init.c index e6592f3bb6..99905f0557 100644 --- a/test/Sema/static-init.c +++ b/test/Sema/static-init.c @@ -5,7 +5,7 @@ static int f = 10; static int b = f; // expected-error {{initializer element is not a compile-time constant}} -float r = (float) &r; // expected-error {{initializer element is not a compile-time constant}} +float r = (float) (intptr_t) &r; // expected-error {{initializer element is not a compile-time constant}} intptr_t s = (intptr_t) &s; _Bool t = &t; -- 2.40.0