From: Steve Naroff Date: Mon, 16 Jul 2007 23:25:18 +0000 (+0000) Subject: Implement semantic analysis for the cast operator. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=16beff840865ce36794e495bce10fd0a3e473ab0;p=clang Implement semantic analysis for the cast operator. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@39943 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Sema/SemaExpr.cpp b/Sema/SemaExpr.cpp index dc2fdebf5e..eba69ee75b 100644 --- a/Sema/SemaExpr.cpp +++ b/Sema/SemaExpr.cpp @@ -473,10 +473,22 @@ ParseCallExpr(ExprTy *Fn, SourceLocation LParenLoc, Action::ExprResult Sema:: ParseCastExpr(SourceLocation LParenLoc, TypeTy *Ty, SourceLocation RParenLoc, ExprTy *Op) { - // If error parsing type, ignore. - assert((Ty != 0) && "ParseCastExpr(): missing type"); - // FIXME: Sema for cast is completely missing. - return new CastExpr(QualType::getFromOpaquePtr(Ty), (Expr*)Op, LParenLoc); + assert((Ty != 0) && (Op != 0) && "ParseCastExpr(): missing type or expr"); + + Expr *castExpr = static_cast(Op); + QualType castType = QualType::getFromOpaquePtr(Ty); + + // C99 6.5.4p2: both the cast type and expression type need to be scalars. + if (!castType->isScalarType()) { + return Diag(LParenLoc, diag::err_typecheck_cond_expect_scalar, + castType.getAsString(), SourceRange(LParenLoc, RParenLoc)); + } + if (!castExpr->getType()->isScalarType()) { + return Diag(castExpr->getLocStart(), + diag::err_typecheck_expect_scalar_operand, + castExpr->getType().getAsString(), castExpr->getSourceRange()); + } + return new CastExpr(castType, castExpr, LParenLoc); } inline QualType Sema::CheckConditionalOperands( // C99 6.5.15 diff --git a/include/clang/Basic/DiagnosticKinds.def b/include/clang/Basic/DiagnosticKinds.def index 8addaa493c..721176147c 100644 --- a/include/clang/Basic/DiagnosticKinds.def +++ b/include/clang/Basic/DiagnosticKinds.def @@ -634,6 +634,8 @@ DIAG(ext_typecheck_passing_discards_qualifiers, EXTENSION, "passing '%0' to '%1' discards qualifiers") DIAG(err_typecheck_cond_expect_scalar, ERROR, "used type '%0' where arithmetic or pointer type is required") +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, "incompatible operand types ('%0' and '%1')") DIAG(ext_typecheck_cond_incompatible_pointers, EXTENSION, diff --git a/test/Parser/check_cast.c b/test/Parser/check_cast.c new file mode 100644 index 0000000000..806cb800fc --- /dev/null +++ b/test/Parser/check_cast.c @@ -0,0 +1,12 @@ +// RUN: clang -parse-ast-check %s +struct foo { + int a; +}; + +int main() { + struct foo xxx; + int i; + + xxx = (struct foo)1; // expected-error {{used type 'struct foo' where arithmetic or pointer type is required}} + i = (int)xxx; // expected-error {{operand of type 'struct foo' where arithmetic or pointer type is required}} +}