aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Naroff <snaroff@apple.com>2008-06-03 12:56:35 +0000
committerSteve Naroff <snaroff@apple.com>2008-06-03 12:56:35 +0000
commit63564b8f8bbe83c236ddf74c257a63fa1341a274 (patch)
tree9c9957ef3d2bff1654176f9f47bc64e890789e15
parent1a78735ade87b547473eff6d630b7569afabb708 (diff)
Allow for a GCC cast extension.
Fixes part of <rdar://problem/5980829> clang on xcode: used type 'NSRange' where arithmetic or pointer type is required. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@51900 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Basic/DiagnosticKinds.def2
-rw-r--r--lib/Sema/SemaExpr.cpp13
2 files changed, 12 insertions, 3 deletions
diff --git a/include/clang/Basic/DiagnosticKinds.def b/include/clang/Basic/DiagnosticKinds.def
index 57b49772db..5f691c97d4 100644
--- a/include/clang/Basic/DiagnosticKinds.def
+++ b/include/clang/Basic/DiagnosticKinds.def
@@ -922,6 +922,8 @@ DIAG(err_typecheck_cond_expect_scalar, ERROR,
"used type '%0' where arithmetic or pointer type is required")
DIAG(ext_typecheck_cond_one_void, EXTENSION,
"C99 forbids conditional expressions with only one void side")
+DIAG(ext_typecheck_cast_nonscalar, EXTENSION,
+ "C99 forbids casting nonscalar to the same type")
DIAG(err_typecheck_expect_scalar_operand, ERROR,
"operand of type '%0' where arithmetic or pointer type is required")
DIAG(err_typecheck_cond_incompatible_operands, ERROR,
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 626e829044..c978acac63 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -845,9 +845,16 @@ ActOnCastExpr(SourceLocation LParenLoc, TypeTy *Ty,
// C99 6.5.4p2: the cast type needs to be void or scalar and the expression
// type needs to be scalar.
if (!castType->isVoidType()) { // Cast to void allows any expr type.
- if (!castType->isScalarType() && !castType->isVectorType())
- return Diag(LParenLoc, diag::err_typecheck_cond_expect_scalar,
- castType.getAsString(), SourceRange(LParenLoc, RParenLoc));
+ if (!castType->isScalarType() && !castType->isVectorType()) {
+ // GCC struct/union extension.
+ if (castType == castExpr->getType() &&
+ castType->isStructureType() || castType->isUnionType())
+ return Diag(LParenLoc, diag::ext_typecheck_cast_nonscalar,
+ SourceRange(LParenLoc, RParenLoc));
+ else
+ return Diag(LParenLoc, diag::err_typecheck_cond_expect_scalar,
+ castType.getAsString(), SourceRange(LParenLoc, RParenLoc));
+ }
if (!castExpr->getType()->isScalarType() &&
!castExpr->getType()->isVectorType())
return Diag(castExpr->getLocStart(),