From 834a72ac74cf4ff07ba6215545dba3db578f8a07 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 25 Jul 2008 23:18:17 +0000 Subject: [PATCH] Fix rdar://6095136, various crashes with incomplete enum types. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@54074 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticKinds.def | 1 + lib/AST/Type.cpp | 13 ++++++++----- lib/Sema/SemaStmt.cpp | 8 +++++++- test/Sema/enum.c | 15 +++++++++++++++ 4 files changed, 31 insertions(+), 6 deletions(-) diff --git a/include/clang/Basic/DiagnosticKinds.def b/include/clang/Basic/DiagnosticKinds.def index d7698d2901..71798a2389 100644 --- a/include/clang/Basic/DiagnosticKinds.def +++ b/include/clang/Basic/DiagnosticKinds.def @@ -961,6 +961,7 @@ DIAG(err_typecheck_expression_not_modifiable_lvalue, ERROR, "expression is not assignable") DIAG(err_typecheck_incomplete_type_not_modifiable_lvalue, ERROR, "incomplete type '%0' is not assignable") + DIAG(err_typecheck_duplicate_vector_components_not_mlvalue, ERROR, "vector is not assignable (contains duplicate components)") DIAG(err_typecheck_call_not_function, ERROR, diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index 0082b2f7b3..275406eaba 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -476,7 +476,8 @@ bool Type::isIntegerType() const { return BT->getKind() >= BuiltinType::Bool && BT->getKind() <= BuiltinType::LongLong; if (const TagType *TT = dyn_cast(CanonicalType)) - if (TT->getDecl()->isEnum()) + // Incomplete enum types are not treated as integer types. + if (TT->getDecl()->isEnum() && TT->getDecl()->isDefinition()) return true; if (const VectorType *VT = dyn_cast(CanonicalType)) return VT->getElementType()->isIntegerType(); @@ -490,8 +491,8 @@ bool Type::isIntegralType() const { return BT->getKind() >= BuiltinType::Bool && BT->getKind() <= BuiltinType::LongLong; if (const TagType *TT = dyn_cast(CanonicalType)) - if (TT->getDecl()->isEnum()) - return true; + if (TT->getDecl()->isEnum() && TT->getDecl()->isDefinition()) + return true; // Complete enum types are integral. if (const ASQualType *ASQT = dyn_cast(CanonicalType)) return ASQT->getBaseType()->isIntegralType(); return false; @@ -593,7 +594,7 @@ bool Type::isRealType() const { return BT->getKind() >= BuiltinType::Bool && BT->getKind() <= BuiltinType::LongDouble; if (const TagType *TT = dyn_cast(CanonicalType)) - return TT->getDecl()->isEnum(); + return TT->getDecl()->isEnum() && TT->getDecl()->isDefinition(); if (const VectorType *VT = dyn_cast(CanonicalType)) return VT->getElementType()->isRealType(); if (const ASQualType *ASQT = dyn_cast(CanonicalType)) @@ -617,7 +618,9 @@ bool Type::isScalarType() const { if (const BuiltinType *BT = dyn_cast(CanonicalType)) return BT->getKind() != BuiltinType::Void; if (const TagType *TT = dyn_cast(CanonicalType)) { - if (TT->getDecl()->isEnum()) + // Enums are scalar types, but only if they are defined. Incomplete enums + // are not treated as scalar types. + if (TT->getDecl()->isEnum() && TT->getDecl()->isDefinition()) return true; return false; } diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 1462d3d57c..a4e8946b45 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -25,6 +25,12 @@ using namespace clang; Sema::StmtResult Sema::ActOnExprStmt(ExprTy *expr) { Expr *E = static_cast(expr); assert(E && "ActOnExprStmt(): missing expression"); + + // C99 6.8.3p2: The expression in an expression statement is evaluated as a + // void expression for its side effects. Conversion to void allows any + // operand, even incomplete types. + + // Same thing in for stmt first clause (when expr) and third clause. return E; } @@ -536,7 +542,7 @@ Sema::ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc, if (!SecondType->isScalarType()) // C99 6.8.5p2 return Diag(ForLoc, diag::err_typecheck_statement_requires_scalar, - SecondType.getAsString(), Second->getSourceRange()); + SecondType.getAsString(), Second->getSourceRange()); } return new ForStmt(First, Second, Third, Body, ForLoc); } diff --git a/test/Sema/enum.c b/test/Sema/enum.c index 2a20d3d7d5..8d184d3d85 100644 --- a/test/Sema/enum.c +++ b/test/Sema/enum.c @@ -33,3 +33,18 @@ int test2(int i) union u0; // expected-error {{previous use is here}} enum u0 { U0A }; // expected-error {{error: use of 'u0' with tag type that does not match previous declaration}} + +// rdar://6095136 +extern enum some_undefined_enum ve2; // expected-warning {{ISO C forbids forward references to 'enum' types}} + +void test4() { + for (; ve2;) // expected-error {{statement requires expression of scalar type}} + ; + (_Bool)ve2; // expected-error {{statement requires expression of scalar type}} + + for (; ;ve2) + ; + (void)ve2; + ve2; +} + -- 2.40.0