]> granicus.if.org Git - clang/commitdiff
Implement semantic analysis for the cast operator.
authorSteve Naroff <snaroff@apple.com>
Mon, 16 Jul 2007 23:25:18 +0000 (23:25 +0000)
committerSteve Naroff <snaroff@apple.com>
Mon, 16 Jul 2007 23:25:18 +0000 (23:25 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@39943 91177308-0d34-0410-b5e6-96231b3b80d8

Sema/SemaExpr.cpp
include/clang/Basic/DiagnosticKinds.def
test/Parser/check_cast.c [new file with mode: 0644]

index dc2fdebf5e1dfa6a402af9b08638ce90f9c36785..eba69ee75b6747e69df6b5ee6f7638e5ca332571 100644 (file)
@@ -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
index 8addaa493c6ab3e5a1e41eae397a0a04e8f28a93..721176147cf34d8b52482755fb655e8d44c40361 100644 (file)
@@ -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 (file)
index 0000000..806cb80
--- /dev/null
@@ -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}}
+}