aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2008-07-25 22:06:10 +0000
committerChris Lattner <sabre@nondot.org>2008-07-25 22:06:10 +0000
commit32b62b6c68ba69799cfca560e3d255897f52887e (patch)
treece2f244fa27b9250246a98915dd83473165f4963
parent9801c8b47a689c0633f7cb4df984aa8c1a52a658 (diff)
Fix a couple bugs in aggregate cast processing: 1) fix precedecence
problem with &&/||. 2) use canonical types for comparison instead of raw types. 3) emit an ext-warn for a gnu extension. Also simplify the code to make it less nested. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@54068 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaExpr.cpp53
1 files changed, 27 insertions, 26 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 27e4027e68..80953da56c 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -1122,33 +1122,34 @@ 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()) {
- // GCC struct/union extension.
- if (castType == castExpr->getType() &&
- castType->isStructureType() || castType->isUnionType()) {
- Diag(LParenLoc, diag::ext_typecheck_cast_nonscalar,
- SourceRange(LParenLoc, RParenLoc));
- return new CastExpr(castType, castExpr, LParenLoc);
- } 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(),
- diag::err_typecheck_expect_scalar_operand,
- castExpr->getType().getAsString(),castExpr->getSourceRange());
-
- if (castExpr->getType()->isVectorType()) {
- if (CheckVectorCast(SourceRange(LParenLoc, RParenLoc),
- castExpr->getType(), castType))
- return true;
- } else if (castType->isVectorType()) {
- if (CheckVectorCast(SourceRange(LParenLoc, RParenLoc),
- castType, castExpr->getType()))
- return true;
+ if (castType->isVoidType()) {
+ // Cast to void allows any expr type.
+ } else if (!castType->isScalarType() && !castType->isVectorType()) {
+ // GCC struct/union extension: allow cast to self.
+ if (Context.getCanonicalType(castType) !=
+ Context.getCanonicalType(castExpr->getType()) ||
+ (!castType->isStructureType() && !castType->isUnionType())) {
+ // Reject any other conversions to non-scalar types.
+ return Diag(LParenLoc, diag::err_typecheck_cond_expect_scalar,
+ castType.getAsString(), castExpr->getSourceRange());
}
+
+ // accept this, but emit an ext-warn.
+ Diag(LParenLoc, diag::ext_typecheck_cast_nonscalar,
+ castType.getAsString(), castExpr->getSourceRange());
+ } else if (!castExpr->getType()->isScalarType() &&
+ !castExpr->getType()->isVectorType()) {
+ return Diag(castExpr->getLocStart(),
+ diag::err_typecheck_expect_scalar_operand,
+ castExpr->getType().getAsString(),castExpr->getSourceRange());
+ } else if (castExpr->getType()->isVectorType()) {
+ if (CheckVectorCast(SourceRange(LParenLoc, RParenLoc),
+ castExpr->getType(), castType))
+ return true;
+ } else if (castType->isVectorType()) {
+ if (CheckVectorCast(SourceRange(LParenLoc, RParenLoc),
+ castType, castExpr->getType()))
+ return true;
}
return new CastExpr(castType, castExpr, LParenLoc);
}