[PATCH] D49952: Check for NULL Destination-Type when creating ArrayConstant
bviyer updated this revision to Diff 159353. https://reviews.llvm.org/D49952 Files: lib/CodeGen/CGExprConstant.cpp test/CodeGenCXX/empty-struct-init-list.cpp Index: test/CodeGenCXX/empty-struct-init-list.cpp === --- /dev/null +++ test/CodeGenCXX/empty-struct-init-list.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -std=c++11 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -std=c++14 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -std=c++17 -emit-llvm -o - %s | FileCheck %s + +// CHECK: struct.a +typedef struct { } a; +typedef struct { + a b[]; +} c; + +// CHECK: global %struct.c zeroinitializer, align 1 +c d{ }; Index: lib/CodeGen/CGExprConstant.cpp === --- lib/CodeGen/CGExprConstant.cpp +++ lib/CodeGen/CGExprConstant.cpp @@ -2119,6 +2119,16 @@ Elts.push_back(C); } +// This means that the array type is probably "IncompleteType" or some +// type that is not ConstantArray. +if (CAT == nullptr && CommonElementType == nullptr && !NumInitElts) { + const ArrayType *AT = CGM.getContext().getAsArrayType(DestType); + CommonElementType = CGM.getTypes().ConvertType(AT->getElementType()); + llvm::ArrayType *AType = llvm::ArrayType::get(CommonElementType, +NumElements); + return llvm::ConstantAggregateZero::get(AType); +} + return EmitArrayConstant(CGM, CAT, CommonElementType, NumElements, Elts, Filler); } Index: test/CodeGenCXX/empty-struct-init-list.cpp === --- /dev/null +++ test/CodeGenCXX/empty-struct-init-list.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -std=c++11 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -std=c++14 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -std=c++17 -emit-llvm -o - %s | FileCheck %s + +// CHECK: struct.a +typedef struct { } a; +typedef struct { + a b[]; +} c; + +// CHECK: global %struct.c zeroinitializer, align 1 +c d{ }; Index: lib/CodeGen/CGExprConstant.cpp === --- lib/CodeGen/CGExprConstant.cpp +++ lib/CodeGen/CGExprConstant.cpp @@ -2119,6 +2119,16 @@ Elts.push_back(C); } +// This means that the array type is probably "IncompleteType" or some +// type that is not ConstantArray. +if (CAT == nullptr && CommonElementType == nullptr && !NumInitElts) { + const ArrayType *AT = CGM.getContext().getAsArrayType(DestType); + CommonElementType = CGM.getTypes().ConvertType(AT->getElementType()); + llvm::ArrayType *AType = llvm::ArrayType::get(CommonElementType, +NumElements); + return llvm::ConstantAggregateZero::get(AType); +} + return EmitArrayConstant(CGM, CAT, CommonElementType, NumElements, Elts, Filler); } ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D49952: Check for NULL Destination-Type when creating ArrayConstant
bviyer marked an inline comment as done. bviyer added a comment. John, I have updated the test case as you requested (I think). I am a bit new to Clang, so apologize if I mistook your request. https://reviews.llvm.org/D49952 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D50122: Complex Variable defined in InitCapture Crash fix
bviyer added a comment. Ping! Repository: rC Clang https://reviews.llvm.org/D50122 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D49766: Fix a crash when an error occurs in Template and the initializer is a nullptr for C++17
bviyer created this revision. bviyer added reviewers: arphaman, erik.pilkington, dexonsmith. Herald added a subscriber: cfe-commits. When the error has occurred for one of the variables inside a template, the Loc function will try to find the end-location of the final item. If this variable is default initialized to nullptr, then the templateArgumentLoc function is invoked. It has an assert to see if the Argument's kind is Expression. If the default initializer is a nullptr, then the argument's kind will be NullPtr, not Expression. This will cause a compiler crash. This patch will allow NullPtr as a possibility for expression's kind. Repository: rC Clang https://reviews.llvm.org/D49766 Files: include/clang/AST/TemplateBase.h test/SemaObjCXX/class-templ-error-null-init.mm Index: test/SemaObjCXX/class-templ-error-null-init.mm === --- /dev/null +++ test/SemaObjCXX/class-templ-error-null-init.mm @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++17 -verify %s + +template // expected-error {{unknown type name 'd'}} +class e { + public: +e(a,b) {} +}; + e c([]{} ,[]{} ); Index: include/clang/AST/TemplateBase.h === --- include/clang/AST/TemplateBase.h +++ include/clang/AST/TemplateBase.h @@ -465,7 +465,14 @@ TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E) : Argument(Argument), LocInfo(E) { -assert(Argument.getKind() == TemplateArgument::Expression); + +/* When an error occurs in a template value that is defaulted to + nullptr then the nullptr is left as-is and this function will + take in an argument that is of type NullPtr when compiled using + C++17 standard. This is to make sure the compiler does not crash + and proceeds through. */ +assert(Argument.getKind() == TemplateArgument::NullPtr || + Argument.getKind() == TemplateArgument::Expression); } TemplateArgumentLoc(const TemplateArgument &Argument, Index: test/SemaObjCXX/class-templ-error-null-init.mm === --- /dev/null +++ test/SemaObjCXX/class-templ-error-null-init.mm @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++17 -verify %s + +template // expected-error {{unknown type name 'd'}} +class e { + public: +e(a,b) {} +}; + e c([]{} ,[]{} ); Index: include/clang/AST/TemplateBase.h === --- include/clang/AST/TemplateBase.h +++ include/clang/AST/TemplateBase.h @@ -465,7 +465,14 @@ TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E) : Argument(Argument), LocInfo(E) { -assert(Argument.getKind() == TemplateArgument::Expression); + +/* When an error occurs in a template value that is defaulted to + nullptr then the nullptr is left as-is and this function will + take in an argument that is of type NullPtr when compiled using + C++17 standard. This is to make sure the compiler does not crash + and proceeds through. */ +assert(Argument.getKind() == TemplateArgument::NullPtr || + Argument.getKind() == TemplateArgument::Expression); } TemplateArgumentLoc(const TemplateArgument &Argument, ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D49766: Fix a crash when an error occurs in Template and the initializer is a nullptr for C++17
bviyer updated this revision to Diff 157721. bviyer added a comment. I have fixed all the changes requested by Erik along with shortening the test case. Repository: rC Clang https://reviews.llvm.org/D49766 Files: include/clang/AST/TemplateBase.h test/SemaObjCXX/class-templ-error-null-init.mm Index: test/SemaObjCXX/class-templ-error-null-init.mm === --- /dev/null +++ test/SemaObjCXX/class-templ-error-null-init.mm @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++17 -verify %s +// expected-no-diagnostics +template +struct e { +e(a) {} +}; +e c(0); Index: include/clang/AST/TemplateBase.h === --- include/clang/AST/TemplateBase.h +++ include/clang/AST/TemplateBase.h @@ -465,7 +465,12 @@ TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E) : Argument(Argument), LocInfo(E) { -assert(Argument.getKind() == TemplateArgument::Expression); + +// Allow more additional argument kinds for the constructor. +assert(Argument.getKind() == TemplateArgument::NullPtr || + Argument.getKind() == TemplateArgument::Integral || + Argument.getKind() == TemplateArgument::Declaration || + Argument.getKind() == TemplateArgument::Expression); } TemplateArgumentLoc(const TemplateArgument &Argument, Index: test/SemaObjCXX/class-templ-error-null-init.mm === --- /dev/null +++ test/SemaObjCXX/class-templ-error-null-init.mm @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++17 -verify %s +// expected-no-diagnostics +template +struct e { +e(a) {} +}; +e c(0); Index: include/clang/AST/TemplateBase.h === --- include/clang/AST/TemplateBase.h +++ include/clang/AST/TemplateBase.h @@ -465,7 +465,12 @@ TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E) : Argument(Argument), LocInfo(E) { -assert(Argument.getKind() == TemplateArgument::Expression); + +// Allow more additional argument kinds for the constructor. +assert(Argument.getKind() == TemplateArgument::NullPtr || + Argument.getKind() == TemplateArgument::Integral || + Argument.getKind() == TemplateArgument::Declaration || + Argument.getKind() == TemplateArgument::Expression); } TemplateArgumentLoc(const TemplateArgument &Argument, ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D49766: Fix a crash when an error occurs in Template and the initializer is a nullptr for C++17
bviyer updated this revision to Diff 157730. bviyer added a comment. Fixed the comment as you suggested. I do not have check in rights yet. Can you please check it in for me? Repository: rC Clang https://reviews.llvm.org/D49766 Files: include/clang/AST/TemplateBase.h test/SemaObjCXX/class-templ-error-null-init.mm Index: test/SemaObjCXX/class-templ-error-null-init.mm === --- /dev/null +++ test/SemaObjCXX/class-templ-error-null-init.mm @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++17 -verify %s +// expected-no-diagnostics +template +struct e { +e(a) {} +}; +e c(0); Index: include/clang/AST/TemplateBase.h === --- include/clang/AST/TemplateBase.h +++ include/clang/AST/TemplateBase.h @@ -465,7 +465,13 @@ TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E) : Argument(Argument), LocInfo(E) { -assert(Argument.getKind() == TemplateArgument::Expression); + +// Permit any kind of template argument that can be represented +// with an expression +assert(Argument.getKind() == TemplateArgument::NullPtr || + Argument.getKind() == TemplateArgument::Integral || + Argument.getKind() == TemplateArgument::Declaration || + Argument.getKind() == TemplateArgument::Expression); } TemplateArgumentLoc(const TemplateArgument &Argument, Index: test/SemaObjCXX/class-templ-error-null-init.mm === --- /dev/null +++ test/SemaObjCXX/class-templ-error-null-init.mm @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++17 -verify %s +// expected-no-diagnostics +template +struct e { +e(a) {} +}; +e c(0); Index: include/clang/AST/TemplateBase.h === --- include/clang/AST/TemplateBase.h +++ include/clang/AST/TemplateBase.h @@ -465,7 +465,13 @@ TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E) : Argument(Argument), LocInfo(E) { -assert(Argument.getKind() == TemplateArgument::Expression); + +// Permit any kind of template argument that can be represented +// with an expression +assert(Argument.getKind() == TemplateArgument::NullPtr || + Argument.getKind() == TemplateArgument::Integral || + Argument.getKind() == TemplateArgument::Declaration || + Argument.getKind() == TemplateArgument::Expression); } TemplateArgumentLoc(const TemplateArgument &Argument, ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D49952: Check for NULL Destination-Type when creating ArrayConstant
bviyer created this revision. bviyer added reviewers: arphaman, dexonsmith, ahatanak, rjmccall. While emitting Array Constant, if the destination type is null-pointer, it will cause an assert. This patch will check if the destination type is null, and if so then it will just return nullptr as the array constant (not something that is derived from destination type). A test case is also attached. Repository: rC Clang https://reviews.llvm.org/D49952 Files: lib/CodeGen/CGExprConstant.cpp test/CodeGenCXX/empty-struct-init-list.cpp Index: test/CodeGenCXX/empty-struct-init-list.cpp === --- /dev/null +++ test/CodeGenCXX/empty-struct-init-list.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -std=c++11 %s +// RUN: %clang_cc1 -std=c++14 %s +// RUN: %clang_cc1 -std=c++17 %s +// expected-no-diagnostics + +typedef struct { } a; + +typedef struct { + a b[]; +} c; +c d{ }; Index: lib/CodeGen/CGExprConstant.cpp === --- lib/CodeGen/CGExprConstant.cpp +++ lib/CodeGen/CGExprConstant.cpp @@ -650,6 +650,8 @@ } if (NonzeroLength == 0) { +if (DestType == nullptr) + return nullptr; return llvm::ConstantAggregateZero::get( CGM.getTypes().ConvertType(QualType(DestType, 0))); } Index: test/CodeGenCXX/empty-struct-init-list.cpp === --- /dev/null +++ test/CodeGenCXX/empty-struct-init-list.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -std=c++11 %s +// RUN: %clang_cc1 -std=c++14 %s +// RUN: %clang_cc1 -std=c++17 %s +// expected-no-diagnostics + +typedef struct { } a; + +typedef struct { + a b[]; +} c; +c d{ }; Index: lib/CodeGen/CGExprConstant.cpp === --- lib/CodeGen/CGExprConstant.cpp +++ lib/CodeGen/CGExprConstant.cpp @@ -650,6 +650,8 @@ } if (NonzeroLength == 0) { +if (DestType == nullptr) + return nullptr; return llvm::ConstantAggregateZero::get( CGM.getTypes().ConvertType(QualType(DestType, 0))); } ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D49952: Check for NULL Destination-Type when creating ArrayConstant
bviyer updated this revision to Diff 158391. bviyer added a comment. Fixed code as suggested by John McCall. Repository: rC Clang https://reviews.llvm.org/D49952 Files: lib/CodeGen/CGExprConstant.cpp test/CodeGenCXX/empty-struct-init-list.cpp Index: test/CodeGenCXX/empty-struct-init-list.cpp === --- /dev/null +++ test/CodeGenCXX/empty-struct-init-list.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -std=c++11 %s +// RUN: %clang_cc1 -std=c++14 %s +// RUN: %clang_cc1 -std=c++17 %s +// expected-no-diagnostics + +typedef struct { } a; + +typedef struct { + a b[]; +} c; +c d{ }; Index: lib/CodeGen/CGExprConstant.cpp === --- lib/CodeGen/CGExprConstant.cpp +++ lib/CodeGen/CGExprConstant.cpp @@ -2119,6 +2119,16 @@ Elts.push_back(C); } +/* This means that the array type is probably "IncompleteType" or some + type that is not ConstantArray. */ +if (CAT == nullptr && CommonElementType == nullptr && !NumInitElts) { + const ArrayType *AT = CGM.getContext().getAsArrayType(DestType); + CommonElementType = CGM.getTypes().ConvertType(AT->getElementType()); + llvm::ArrayType *AType = llvm::ArrayType::get(CommonElementType, +NumElements); + return llvm::ConstantAggregateZero::get(AType); +} + return EmitArrayConstant(CGM, CAT, CommonElementType, NumElements, Elts, Filler); } Index: test/CodeGenCXX/empty-struct-init-list.cpp === --- /dev/null +++ test/CodeGenCXX/empty-struct-init-list.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -std=c++11 %s +// RUN: %clang_cc1 -std=c++14 %s +// RUN: %clang_cc1 -std=c++17 %s +// expected-no-diagnostics + +typedef struct { } a; + +typedef struct { + a b[]; +} c; +c d{ }; Index: lib/CodeGen/CGExprConstant.cpp === --- lib/CodeGen/CGExprConstant.cpp +++ lib/CodeGen/CGExprConstant.cpp @@ -2119,6 +2119,16 @@ Elts.push_back(C); } +/* This means that the array type is probably "IncompleteType" or some + type that is not ConstantArray. */ +if (CAT == nullptr && CommonElementType == nullptr && !NumInitElts) { + const ArrayType *AT = CGM.getContext().getAsArrayType(DestType); + CommonElementType = CGM.getTypes().ConvertType(AT->getElementType()); + llvm::ArrayType *AType = llvm::ArrayType::get(CommonElementType, +NumElements); + return llvm::ConstantAggregateZero::get(AType); +} + return EmitArrayConstant(CGM, CAT, CommonElementType, NumElements, Elts, Filler); } ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D49952: Check for NULL Destination-Type when creating ArrayConstant
bviyer updated this revision to Diff 158392. bviyer added a comment. Forgot to pass the -emit-llvm to the test case. https://reviews.llvm.org/D49952 Files: lib/CodeGen/CGExprConstant.cpp test/CodeGenCXX/empty-struct-init-list.cpp Index: test/CodeGenCXX/empty-struct-init-list.cpp === --- /dev/null +++ test/CodeGenCXX/empty-struct-init-list.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -std=c++11 -emit-llvm %s +// RUN: %clang_cc1 -std=c++14 -emit-llvm %s +// RUN: %clang_cc1 -std=c++17 -emit-llvm %s +// expected-no-diagnostics + +typedef struct { } a; + +typedef struct { + a b[]; +} c; +c d{ }; Index: lib/CodeGen/CGExprConstant.cpp === --- lib/CodeGen/CGExprConstant.cpp +++ lib/CodeGen/CGExprConstant.cpp @@ -2119,6 +2119,16 @@ Elts.push_back(C); } +/* This means that the array type is probably "IncompleteType" or some + type that is not ConstantArray. */ +if (CAT == nullptr && CommonElementType == nullptr && !NumInitElts) { + const ArrayType *AT = CGM.getContext().getAsArrayType(DestType); + CommonElementType = CGM.getTypes().ConvertType(AT->getElementType()); + llvm::ArrayType *AType = llvm::ArrayType::get(CommonElementType, +NumElements); + return llvm::ConstantAggregateZero::get(AType); +} + return EmitArrayConstant(CGM, CAT, CommonElementType, NumElements, Elts, Filler); } Index: test/CodeGenCXX/empty-struct-init-list.cpp === --- /dev/null +++ test/CodeGenCXX/empty-struct-init-list.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -std=c++11 -emit-llvm %s +// RUN: %clang_cc1 -std=c++14 -emit-llvm %s +// RUN: %clang_cc1 -std=c++17 -emit-llvm %s +// expected-no-diagnostics + +typedef struct { } a; + +typedef struct { + a b[]; +} c; +c d{ }; Index: lib/CodeGen/CGExprConstant.cpp === --- lib/CodeGen/CGExprConstant.cpp +++ lib/CodeGen/CGExprConstant.cpp @@ -2119,6 +2119,16 @@ Elts.push_back(C); } +/* This means that the array type is probably "IncompleteType" or some + type that is not ConstantArray. */ +if (CAT == nullptr && CommonElementType == nullptr && !NumInitElts) { + const ArrayType *AT = CGM.getContext().getAsArrayType(DestType); + CommonElementType = CGM.getTypes().ConvertType(AT->getElementType()); + llvm::ArrayType *AType = llvm::ArrayType::get(CommonElementType, +NumElements); + return llvm::ConstantAggregateZero::get(AType); +} + return EmitArrayConstant(CGM, CAT, CommonElementType, NumElements, Elts, Filler); } ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D50122: Complex Variable defined in InitCapture Crash fix
bviyer created this revision. bviyer added reviewers: erik.pilkington, ahatanak, arphaman, dexonsmith. Herald added a subscriber: cfe-commits. When a variable is defined in the init capture and it is of type struct that is dependent on additional structure, its definition is not found. An exception is created in the findInstantiatedDecl () function. Repository: rC Clang https://reviews.llvm.org/D50122 Files: lib/Sema/SemaTemplateInstantiate.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp test/SemaCXX/lambda-init-capture-vardefine.cpp Index: test/SemaCXX/lambda-init-capture-vardefine.cpp === --- /dev/null +++ test/SemaCXX/lambda-init-capture-vardefine.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -std=c++14 -fsyntax-only -verify %s +// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s +// expected-no-diagnostics + +template using a = void; +template struct c { static const int d = b; }; +template > struct e : c {}; +template g h(int); +template decltype(h(0)) i; +template struct e())>>; +template auto func(k &&); +template struct l { + template static auto n(k o) { +return [f{o}](auto) { func([](auto...) -> decltype(f) {}); }; + } +}; +template auto func(k &&o) { return l::d>::n(o); } +int main(void) { + auto f = [](auto) {}; + func(f)(1); +} Index: lib/Sema/SemaTemplateInstantiateDecl.cpp === --- lib/Sema/SemaTemplateInstantiateDecl.cpp +++ lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -4962,6 +4962,14 @@ return cast(Inst); } +// If the variable is in InitCapture and variable types are of type +// mentioned in the above comment (the comment starting as "Normally +// this function...") then its existance won't be known so we have to +// make an exclusion for them. +if (const VarDecl *VD = dyn_cast(D)) + if (VD->isInitCapture()) +return nullptr; + // If we didn't find the decl, then we must have a label decl that hasn't // been found yet. Lazily instantiate it and return it now. assert(isa(D)); Index: lib/Sema/SemaTemplateInstantiate.cpp === --- lib/Sema/SemaTemplateInstantiate.cpp +++ lib/Sema/SemaTemplateInstantiate.cpp @@ -2913,6 +2913,9 @@ // error recovery. if (isa(D)) return nullptr; + if (const VarDecl *VD = dyn_cast(D)) +if (VD->isInitCapture()) + return nullptr; // If we didn't find the decl, then we either have a sema bug, or we have a // forward reference to a label declaration. Return null to indicate that Index: test/SemaCXX/lambda-init-capture-vardefine.cpp === --- /dev/null +++ test/SemaCXX/lambda-init-capture-vardefine.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -std=c++14 -fsyntax-only -verify %s +// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s +// expected-no-diagnostics + +template using a = void; +template struct c { static const int d = b; }; +template > struct e : c {}; +template g h(int); +template decltype(h(0)) i; +template struct e())>>; +template auto func(k &&); +template struct l { + template static auto n(k o) { +return [f{o}](auto) { func([](auto...) -> decltype(f) {}); }; + } +}; +template auto func(k &&o) { return l::d>::n(o); } +int main(void) { + auto f = [](auto) {}; + func(f)(1); +} Index: lib/Sema/SemaTemplateInstantiateDecl.cpp === --- lib/Sema/SemaTemplateInstantiateDecl.cpp +++ lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -4962,6 +4962,14 @@ return cast(Inst); } +// If the variable is in InitCapture and variable types are of type +// mentioned in the above comment (the comment starting as "Normally +// this function...") then its existance won't be known so we have to +// make an exclusion for them. +if (const VarDecl *VD = dyn_cast(D)) + if (VD->isInitCapture()) +return nullptr; + // If we didn't find the decl, then we must have a label decl that hasn't // been found yet. Lazily instantiate it and return it now. assert(isa(D)); Index: lib/Sema/SemaTemplateInstantiate.cpp === --- lib/Sema/SemaTemplateInstantiate.cpp +++ lib/Sema/SemaTemplateInstantiate.cpp @@ -2913,6 +2913,9 @@ // error recovery. if (isa(D)) return nullptr; + if (const VarDecl *VD = dyn_cast(D)) +if (VD->isInitCapture()) + return nullptr; // If we didn't find the decl, then we either have a sema bug, or we have a // forward reference to a label declaration. Return null to indicate that ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D49952: Check for NULL Destination-Type when creating ArrayConstant
bviyer updated this revision to Diff 158676. bviyer added a comment. Added FileCheck as requested by John McCall Made comments start with "//" instead of /* Removed expected-no-diagnostics from the test case (as requested by Erik) Repository: rC Clang https://reviews.llvm.org/D49952 Files: lib/CodeGen/CGExprConstant.cpp test/CodeGenCXX/empty-struct-init-list.cpp Index: test/CodeGenCXX/empty-struct-init-list.cpp === --- /dev/null +++ test/CodeGenCXX/empty-struct-init-list.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -std=c++11 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -std=c++14 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -std=c++17 -emit-llvm -o - %s | FileCheck %s + +// CHECK: struct.a +typedef struct { } a; +typedef struct { + a b[]; +} c; + +// CHECK: struct.c +c d{ }; Index: lib/CodeGen/CGExprConstant.cpp === --- lib/CodeGen/CGExprConstant.cpp +++ lib/CodeGen/CGExprConstant.cpp @@ -2119,6 +2119,16 @@ Elts.push_back(C); } +// This means that the array type is probably "IncompleteType" or some +// type that is not ConstantArray. +if (CAT == nullptr && CommonElementType == nullptr && !NumInitElts) { + const ArrayType *AT = CGM.getContext().getAsArrayType(DestType); + CommonElementType = CGM.getTypes().ConvertType(AT->getElementType()); + llvm::ArrayType *AType = llvm::ArrayType::get(CommonElementType, +NumElements); + return llvm::ConstantAggregateZero::get(AType); +} + return EmitArrayConstant(CGM, CAT, CommonElementType, NumElements, Elts, Filler); } Index: test/CodeGenCXX/empty-struct-init-list.cpp === --- /dev/null +++ test/CodeGenCXX/empty-struct-init-list.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -std=c++11 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -std=c++14 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -std=c++17 -emit-llvm -o - %s | FileCheck %s + +// CHECK: struct.a +typedef struct { } a; +typedef struct { + a b[]; +} c; + +// CHECK: struct.c +c d{ }; Index: lib/CodeGen/CGExprConstant.cpp === --- lib/CodeGen/CGExprConstant.cpp +++ lib/CodeGen/CGExprConstant.cpp @@ -2119,6 +2119,16 @@ Elts.push_back(C); } +// This means that the array type is probably "IncompleteType" or some +// type that is not ConstantArray. +if (CAT == nullptr && CommonElementType == nullptr && !NumInitElts) { + const ArrayType *AT = CGM.getContext().getAsArrayType(DestType); + CommonElementType = CGM.getTypes().ConvertType(AT->getElementType()); + llvm::ArrayType *AType = llvm::ArrayType::get(CommonElementType, +NumElements); + return llvm::ConstantAggregateZero::get(AType); +} + return EmitArrayConstant(CGM, CAT, CommonElementType, NumElements, Elts, Filler); } ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D50122: Complex Variable defined in InitCapture Crash fix
bviyer updated this revision to Diff 158870. bviyer added a comment. Simplified the case a bit more as requested by Erik. I also induced some errors in the test so that if someone symbolic-linked clang to /bin/true, the test will fail. Repository: rC Clang https://reviews.llvm.org/D50122 Files: lib/Sema/SemaTemplateInstantiate.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp test/SemaCXX/lambda-init-capture-vardefine.cpp Index: test/SemaCXX/lambda-init-capture-vardefine.cpp === --- /dev/null +++ test/SemaCXX/lambda-init-capture-vardefine.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -std=c++14 -fsyntax-only -verify %s +// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s + +template void func(k&&); + +template +void n(k o) { +[f = o](auto) { // expected-note + {{instantiation of function template}} +func([](auto)->int { return sizeof(f); }); // expected-error{{recursive template instantiation exceeded}} expected-note + {{instantiation of function template}} +}(0); +} + +template +void func(k &&o) +{ +o(0); +n(o); // expected-note + {{instantiation of function template}} expected-note + {{skipping}} +} + +int main() { +auto f = [](auto) {}; +func(f); // expected-note + {{instantiation of function template}} +} Index: lib/Sema/SemaTemplateInstantiateDecl.cpp === --- lib/Sema/SemaTemplateInstantiateDecl.cpp +++ lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -4962,6 +4962,14 @@ return cast(Inst); } +// If the variable is in InitCapture and variable types are of type +// mentioned in the above comment (the comment starting as "Normally +// this function...") then its existance won't be known so we have to +// make an exclusion for them. +if (const VarDecl *VD = dyn_cast(D)) + if (VD->isInitCapture()) +return nullptr; + // If we didn't find the decl, then we must have a label decl that hasn't // been found yet. Lazily instantiate it and return it now. assert(isa(D)); Index: lib/Sema/SemaTemplateInstantiate.cpp === --- lib/Sema/SemaTemplateInstantiate.cpp +++ lib/Sema/SemaTemplateInstantiate.cpp @@ -2913,6 +2913,9 @@ // error recovery. if (isa(D)) return nullptr; + if (const VarDecl *VD = dyn_cast(D)) +if (VD->isInitCapture()) + return nullptr; // If we didn't find the decl, then we either have a sema bug, or we have a // forward reference to a label declaration. Return null to indicate that Index: test/SemaCXX/lambda-init-capture-vardefine.cpp === --- /dev/null +++ test/SemaCXX/lambda-init-capture-vardefine.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -std=c++14 -fsyntax-only -verify %s +// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s + +template void func(k&&); + +template +void n(k o) { +[f = o](auto) { // expected-note + {{instantiation of function template}} +func([](auto)->int { return sizeof(f); }); // expected-error{{recursive template instantiation exceeded}} expected-note + {{instantiation of function template}} +}(0); +} + +template +void func(k &&o) +{ +o(0); +n(o); // expected-note + {{instantiation of function template}} expected-note + {{skipping}} +} + +int main() { +auto f = [](auto) {}; +func(f); // expected-note + {{instantiation of function template}} +} Index: lib/Sema/SemaTemplateInstantiateDecl.cpp === --- lib/Sema/SemaTemplateInstantiateDecl.cpp +++ lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -4962,6 +4962,14 @@ return cast(Inst); } +// If the variable is in InitCapture and variable types are of type +// mentioned in the above comment (the comment starting as "Normally +// this function...") then its existance won't be known so we have to +// make an exclusion for them. +if (const VarDecl *VD = dyn_cast(D)) + if (VD->isInitCapture()) +return nullptr; + // If we didn't find the decl, then we must have a label decl that hasn't // been found yet. Lazily instantiate it and return it now. assert(isa(D)); Index: lib/Sema/SemaTemplateInstantiate.cpp === --- lib/Sema/SemaTemplateInstantiate.cpp +++ lib/Sema/SemaTemplateInstantiate.cpp @@ -2913,6 +2913,9 @@ // error recovery. if (isa(D)) return nullptr; + if (const VarDecl *VD = dyn_cast(D)) +if (VD->isInitCapture()) + return nullptr; // If we didn't find the decl, then we either have a sema bug, or we have a // forward reference to a label declaration. Return null to indicate that ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.
[PATCH] D48506: Fix for Crash in nested name specifier decltype
bviyer created this revision. bviyer added reviewers: rsmith, arphaman. There was a crash when qualtype is null in the function Sema::ActOnCXXNestedNameSpecifierDecltype. If it is null then just return without processing it further. Repository: rC Clang https://reviews.llvm.org/D48506 Files: lib/Sema/SemaCXXScopeSpec.cpp test/SemaCXX/qualtype-null-check.cpp Index: test/SemaCXX/qualtype-null-check.cpp === --- /dev/null +++ test/SemaCXX/qualtype-null-check.cpp @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++14 -verify %s +struct A +{ +bool x{&decltype(foo)::foo}; // expected-error {{reference to non-static member function must be called}} +void foo(int); +}; Index: lib/Sema/SemaCXXScopeSpec.cpp === --- lib/Sema/SemaCXXScopeSpec.cpp +++ lib/Sema/SemaCXXScopeSpec.cpp @@ -846,6 +846,8 @@ assert(DS.getTypeSpecType() == DeclSpec::TST_decltype); QualType T = BuildDecltypeType(DS.getRepAsExpr(), DS.getTypeSpecTypeLoc()); + if (T.getTypePtrOrNull() == nullptr) + return true; if (!T->isDependentType() && !T->getAs()) { Diag(DS.getTypeSpecTypeLoc(), diag::err_expected_class_or_namespace) << T << getLangOpts().CPlusPlus; Index: test/SemaCXX/qualtype-null-check.cpp === --- /dev/null +++ test/SemaCXX/qualtype-null-check.cpp @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++14 -verify %s +struct A +{ +bool x{&decltype(foo)::foo}; // expected-error {{reference to non-static member function must be called}} +void foo(int); +}; Index: lib/Sema/SemaCXXScopeSpec.cpp === --- lib/Sema/SemaCXXScopeSpec.cpp +++ lib/Sema/SemaCXXScopeSpec.cpp @@ -846,6 +846,8 @@ assert(DS.getTypeSpecType() == DeclSpec::TST_decltype); QualType T = BuildDecltypeType(DS.getRepAsExpr(), DS.getTypeSpecTypeLoc()); + if (T.getTypePtrOrNull() == nullptr) + return true; if (!T->isDependentType() && !T->getAs()) { Diag(DS.getTypeSpecTypeLoc(), diag::err_expected_class_or_namespace) << T << getLangOpts().CPlusPlus; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D48506: Fix for Crash in nested name specifier decltype
bviyer added a comment. Herald added a subscriber: dexonsmith. Ping! Repository: rC Clang https://reviews.llvm.org/D48506 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D48506: Fix for Crash in nested name specifier decltype
bviyer abandoned this revision. bviyer added a comment. Thank you Eric. I abandoned the revision as you suggested. Repository: rC Clang https://reviews.llvm.org/D48506 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits