aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Naroff <snaroff@apple.com>2007-07-16 23:25:18 +0000
committerSteve Naroff <snaroff@apple.com>2007-07-16 23:25:18 +0000
commit16beff840865ce36794e495bce10fd0a3e473ab0 (patch)
treeb373e4675034d8f48d9c692d3c7356d6622522b5
parent3e5e5560b3300b6bed669c6743c52d995e5d8a8d (diff)
Implement semantic analysis for the cast operator.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@39943 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--Sema/SemaExpr.cpp20
-rw-r--r--include/clang/Basic/DiagnosticKinds.def2
-rw-r--r--test/Parser/check_cast.c12
3 files changed, 30 insertions, 4 deletions
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<Expr*>(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}}
+}