diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index cde2de9819a8..5c21b0762bf2 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -935,20 +935,6 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) { const Type *ty = type.getTypePtr(); switch (ty->getTypeClass()) { - default: - // Only sugared types (different from typeof_expr) can reach this point. - assert(!type.isCanonical() && "unhandled canonical type!"); - type = type.getSingleStepDesugaredType(getContext()); - break; - - case Type::TypeOfExpr: { - // This is the only sugared type requiring special treatment. - // Emit typeof expression and we are done. - Expr *E = cast(ty)->getUnderlyingExpr(); - EmitIgnoredExpr(E); - return; - } - #define TYPE(Class, Base) #define ABSTRACT_TYPE(Class, Base) #define NON_CANONICAL_TYPE(Class, Base) @@ -964,6 +950,8 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) { case Type::ExtVector: case Type::Record: case Type::Enum: + case Type::Elaborated: + case Type::TemplateSpecialization: case Type::ObjCObject: case Type::ObjCInterface: case Type::ObjCObjectPointer: @@ -1018,6 +1006,26 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) { type = cast(ty)->getResultType(); break; + case Type::Paren: + case Type::TypeOf: + case Type::UnaryTransform: + case Type::Attributed: + case Type::SubstTemplateTypeParm: + // Keep walking after single level desugaring. + type = type.getSingleStepDesugaredType(getContext()); + break; + + case Type::Typedef: + case Type::Decltype: + case Type::Auto: + // Stop walking: nothing to do. + return; + + case Type::TypeOfExpr: + // Stop walking: emit typeof expression. + EmitIgnoredExpr(cast(ty)->getUnderlyingExpr()); + return; + case Type::Atomic: type = cast(ty)->getValueType(); break; diff --git a/clang/test/CodeGen/vla-4.c b/clang/test/CodeGen/vla-4.c new file mode 100644 index 000000000000..5c1d131ea32d --- /dev/null +++ b/clang/test/CodeGen/vla-4.c @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s + +int f(); +int h(); + +void t1() { + _Atomic(typeof((int (*)[f()]) h())) v; + // CHECK: [[N:%.*]] = alloca i32*, align 4 + // CHECK-NEXT: [[P:%.*]] = call i32 bitcast (i32 (...)* @f to i32 ()*)() + // CHECK-NEXT: [[P:%.*]] = call i32 bitcast (i32 (...)* @h to i32 ()*)() +} + +void t2() { + typeof(typeof((int (*)[f()]) h())) v; + // CHECK: [[N:%.*]] = alloca i32*, align 4 + // CHECK-NEXT: [[P:%.*]] = call i32 bitcast (i32 (...)* @f to i32 ()*)() + // CHECK-NEXT: [[P:%.*]] = call i32 bitcast (i32 (...)* @h to i32 ()*)() +} + +void t3(typeof((int (*)[f()]) h()) v) { + // CHECK: store i32* %v, i32** %v.addr, align 4 + // CHECK-NEXT: [[P:%.*]] = call i32 bitcast (i32 (...)* @f to i32 ()*)() + // CHECK-NEXT: [[P:%.*]] = call i32 bitcast (i32 (...)* @h to i32 ()*)() +}