From: Chris Lattner Date: Fri, 25 Jul 2008 22:06:10 +0000 (+0000) Subject: Fix a couple bugs in aggregate cast processing: 1) fix precedecence X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=32b62b6c68ba69799cfca560e3d255897f52887e;p=clang 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 --- 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); }