Skip to content

Commit 0e06b86

Browse files
author
MUSTAPHA BARKI
authored
Merge branch 'llvm:main' into Uncontrolled-data-used-in-path-expression
2 parents dc52282 + fc525bf commit 0e06b86

File tree

34 files changed

+890
-190
lines changed

34 files changed

+890
-190
lines changed

clang-tools-extra/test/clang-tidy/checkers/modernize/type-traits.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,25 @@ namespace std {
1414
static constexpr bool value = true;
1515
};
1616

17+
template <typename T, typename U>
18+
static constexpr bool is_same_v = is_same<T, U>::value; // NOLINT
19+
1720
template<bool, typename T = void>
1821
struct enable_if {
1922
using type = T;
2023
};
2124

25+
template <bool B, typename T = void>
26+
using enable_if_t = typename enable_if<B, T>::type; // NOLINT
27+
28+
template <typename T>
29+
struct remove_reference {
30+
using type = T;
31+
};
32+
33+
template <typename T>
34+
using remove_reference_t = typename remove_reference<T>::type; // NOLINT
35+
2236
template <typename...>
2337
struct common_type {
2438
using type = int;
@@ -126,3 +140,13 @@ namespace my_std = std;
126140
using Alias = my_std::add_const<bool>::type;
127141
// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use c++14 style type templates
128142
// CHECK-FIXES: using Alias = my_std::add_const_t<bool>;
143+
144+
template <typename T>
145+
struct ImplicitlyInstantiatedConstructor {
146+
template <typename U, typename = std::enable_if_t<std::is_same_v<U, T>>>
147+
ImplicitlyInstantiatedConstructor(U) {}
148+
};
149+
150+
const ImplicitlyInstantiatedConstructor<int> ImplicitInstantiation(std::remove_reference<int>::type(123));
151+
// CHECK-MESSAGES: :[[@LINE-1]]:68: warning: use c++14 style type templates
152+
// CHECK-FIXES: const ImplicitlyInstantiatedConstructor<int> ImplicitInstantiation(std::remove_reference_t<int>(123));

clang/include/clang/AST/RecursiveASTVisitor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2194,6 +2194,7 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLocsHelper(
21942194
is the only callback that's made for this instantiation. \
21952195
We use getTemplateArgsAsWritten() to distinguish. */ \
21962196
if (const auto *ArgsWritten = D->getTemplateArgsAsWritten()) { \
2197+
assert(D->getTemplateSpecializationKind() != TSK_ImplicitInstantiation); \
21972198
/* The args that remains unspecialized. */ \
21982199
TRY_TO(TraverseTemplateArgumentLocsHelper( \
21992200
ArgsWritten->getTemplateArgs(), ArgsWritten->NumTemplateArgs)); \

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1777,7 +1777,8 @@ def note_unsatisfied_trait
17771777
"%Empty{empty}|"
17781778
"%StandardLayout{standard-layout}|"
17791779
"%Aggregate{aggregate}|"
1780-
"%Final{final}"
1780+
"%Final{final}|"
1781+
"%Abstract{abstract}"
17811782
"}1">;
17821783

17831784
def note_unsatisfied_trait_reason
@@ -1827,7 +1828,12 @@ def note_unsatisfied_trait_reason
18271828
"%PrivateProtectedDirectDataMember{has a %select{private|protected}1 direct data member}|"
18281829
"%PrivateProtectedDirectBase{has a %select{private|protected}1 direct base}|"
18291830
"%NotClassOrUnion{is not a class or union type}|"
1830-
"%NotMarkedFinal{is not marked 'final'}"
1831+
"%NotMarkedFinal{is not marked 'final'}|"
1832+
"%PointerType{is a pointer type}|"
1833+
"%ArrayType{is an array type}|"
1834+
"%UnionType{is a union type}|"
1835+
"%NotStructOrClass{is not a struct or class type}|"
1836+
"%OverridesAllPureVirtual{overrides all pure virtual functions from base class %1}"
18311837
"}0">;
18321838

18331839
def warn_consteval_if_always_true : Warning<

clang/lib/Sema/SemaTypeTraits.cpp

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2014,6 +2014,7 @@ static std::optional<TypeTrait> StdNameToTypeTrait(StringRef Name) {
20142014
.Case("is_aggregate", TypeTrait::UTT_IsAggregate)
20152015
.Case("is_constructible", TypeTrait::TT_IsConstructible)
20162016
.Case("is_final", TypeTrait::UTT_IsFinal)
2017+
.Case("is_abstract", TypeTrait::UTT_IsAbstract)
20172018
.Default(std::nullopt);
20182019
}
20192020

@@ -2774,6 +2775,75 @@ static void DiagnoseNonAggregateReason(Sema &SemaRef, SourceLocation Loc,
27742775
DiagnoseNonAggregateReason(SemaRef, Loc, D);
27752776
}
27762777

2778+
static void DiagnoseNonAbstractReason(Sema &SemaRef, SourceLocation Loc,
2779+
const CXXRecordDecl *D) {
2780+
// If this type has any abstract base classes, their respective virtual
2781+
// functions must have been overridden.
2782+
for (const CXXBaseSpecifier &B : D->bases()) {
2783+
if (B.getType()->castAsCXXRecordDecl()->isAbstract()) {
2784+
SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2785+
<< diag::TraitNotSatisfiedReason::OverridesAllPureVirtual
2786+
<< B.getType() << B.getSourceRange();
2787+
}
2788+
}
2789+
}
2790+
2791+
static void DiagnoseNonAbstractReason(Sema &SemaRef, SourceLocation Loc,
2792+
QualType T) {
2793+
SemaRef.Diag(Loc, diag::note_unsatisfied_trait)
2794+
<< T << diag::TraitName::Abstract;
2795+
2796+
if (T->isReferenceType()) {
2797+
SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2798+
<< diag::TraitNotSatisfiedReason::Ref;
2799+
SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2800+
<< diag::TraitNotSatisfiedReason::NotStructOrClass;
2801+
return;
2802+
}
2803+
2804+
if (T->isUnionType()) {
2805+
SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2806+
<< diag::TraitNotSatisfiedReason::UnionType;
2807+
SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2808+
<< diag::TraitNotSatisfiedReason::NotStructOrClass;
2809+
return;
2810+
}
2811+
2812+
if (SemaRef.Context.getAsArrayType(T)) {
2813+
SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2814+
<< diag::TraitNotSatisfiedReason::ArrayType;
2815+
SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2816+
<< diag::TraitNotSatisfiedReason::NotStructOrClass;
2817+
return;
2818+
}
2819+
2820+
if (T->isFunctionType()) {
2821+
SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2822+
<< diag::TraitNotSatisfiedReason::FunctionType;
2823+
SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2824+
<< diag::TraitNotSatisfiedReason::NotStructOrClass;
2825+
return;
2826+
}
2827+
2828+
if (T->isPointerType()) {
2829+
SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2830+
<< diag::TraitNotSatisfiedReason::PointerType;
2831+
SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2832+
<< diag::TraitNotSatisfiedReason::NotStructOrClass;
2833+
return;
2834+
}
2835+
2836+
if (!T->isStructureOrClassType()) {
2837+
SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2838+
<< diag::TraitNotSatisfiedReason::NotStructOrClass;
2839+
return;
2840+
}
2841+
2842+
const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2843+
if (D->hasDefinition())
2844+
DiagnoseNonAbstractReason(SemaRef, Loc, D);
2845+
}
2846+
27772847
void Sema::DiagnoseTypeTraitDetails(const Expr *E) {
27782848
E = E->IgnoreParenImpCasts();
27792849
if (E->containsErrors())
@@ -2818,6 +2888,9 @@ void Sema::DiagnoseTypeTraitDetails(const Expr *E) {
28182888
DiagnoseIsFinalReason(*this, E->getBeginLoc(), QT); // unsatisfied
28192889
break;
28202890
}
2891+
case UTT_IsAbstract:
2892+
DiagnoseNonAbstractReason(*this, E->getBeginLoc(), Args[0]);
2893+
break;
28212894
default:
28222895
break;
28232896
}

clang/test/CodeGen/X86/avx2-builtins.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ __m256i test_mm_broadcastsi128_si256(__m128i a) {
263263
// CHECK: shufflevector <2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <4 x i32> <i32 0, i32 1, i32 0, i32 1>
264264
return _mm_broadcastsi128_si256(a);
265265
}
266+
TEST_CONSTEXPR(match_m256i(_mm_broadcastsi128_si256(((__m128i)(__v2di){42, -99})), 42, -99, 42, -99));
266267

267268
__m128 test_mm_broadcastss_ps(__m128 a) {
268269
// CHECK-LABEL: test_mm_broadcastss_ps

clang/test/SemaCXX/type-traits-unsatisfied-diags-std.cpp

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,13 @@ struct is_final {
6666
template <typename T>
6767
constexpr bool is_final_v = __is_final(T);
6868

69+
template <typename T>
70+
struct is_abstract {
71+
static constexpr bool value = __is_abstract(T);
72+
};
73+
template <typename T>
74+
constexpr bool is_abstract_v = __is_abstract(T);
75+
6976
#endif
7077

7178
#ifdef STD2
@@ -151,6 +158,15 @@ using is_final = __details_is_final<T>;
151158
template <typename T>
152159
constexpr bool is_final_v = __is_final(T);
153160

161+
template <typename T>
162+
struct __details_is_abstract {
163+
static constexpr bool value = __is_abstract(T);
164+
};
165+
template <typename T>
166+
using is_abstract = __details_is_abstract<T>;
167+
template <typename T>
168+
constexpr bool is_abstract_v = __is_abstract(T);
169+
154170
#endif
155171

156172

@@ -229,6 +245,13 @@ using is_final = __details_is_final<T>;
229245
template <typename T>
230246
constexpr bool is_final_v = is_final<T>::value;
231247

248+
template <typename T>
249+
struct __details_is_abstract : bool_constant<__is_abstract(T)> {};
250+
template <typename T>
251+
using is_abstract = __details_is_abstract<T>;
252+
template <typename T>
253+
constexpr bool is_abstract_v = is_abstract<T>::value;
254+
232255
#endif
233256
}
234257

@@ -336,6 +359,22 @@ static_assert(std::is_aggregate_v<void>);
336359
// expected-note@-1 {{'void' is not aggregate}} \
337360
// expected-note@-1 {{because it is a cv void type}}
338361

362+
363+
static_assert(!std::is_abstract<int>::value);
364+
365+
static_assert(std::is_abstract<int&>::value);
366+
// expected-error-re@-1 {{static assertion failed due to requirement 'std::{{.*}}is_abstract<int &>::value'}} \
367+
// expected-note@-1 {{'int &' is not abstract}} \
368+
// expected-note@-1 {{because it is a reference type}} \
369+
// expected-note@-1 {{because it is not a struct or class type}}
370+
371+
static_assert(std::is_abstract_v<int&>);
372+
// expected-error@-1 {{static assertion failed due to requirement 'std::is_abstract_v<int &>'}} \
373+
// expected-note@-1 {{'int &' is not abstract}} \
374+
// expected-note@-1 {{because it is a reference type}} \
375+
// expected-note@-1 {{because it is not a struct or class type}}
376+
377+
339378
namespace test_namespace {
340379
using namespace std;
341380
static_assert(is_trivially_relocatable<int&>::value);
@@ -388,7 +427,7 @@ namespace test_namespace {
388427
static_assert(is_constructible_v<void>);
389428
// expected-error@-1 {{static assertion failed due to requirement 'is_constructible_v<void>'}} \
390429
// expected-note@-1 {{because it is a cv void type}}
391-
430+
392431
static_assert(std::is_aggregate<void>::value);
393432
// expected-error-re@-1 {{static assertion failed due to requirement 'std::{{.*}}is_aggregate<void>::value'}} \
394433
// expected-note@-1 {{'void' is not aggregate}} \
@@ -422,6 +461,18 @@ namespace test_namespace {
422461
// expected-note@-1 {{'Fn' (aka 'void ()') is not final}} \
423462
// expected-note@-1 {{because it is a function type}} \
424463
// expected-note@-1 {{because it is not a class or union type}}
464+
465+
static_assert(is_abstract<int&>::value);
466+
// expected-error-re@-1 {{static assertion failed due to requirement '{{.*}}is_abstract<int &>::value'}} \
467+
// expected-note@-1 {{'int &' is not abstract}} \
468+
// expected-note@-1 {{because it is a reference type}} \
469+
// expected-note@-1 {{because it is not a struct or class type}}
470+
471+
static_assert(is_abstract_v<int&>);
472+
// expected-error@-1 {{static assertion failed due to requirement 'is_abstract_v<int &>'}} \
473+
// expected-note@-1 {{'int &' is not abstract}} \
474+
// expected-note@-1 {{because it is a reference type}} \
475+
// expected-note@-1 {{because it is not a struct or class type}}
425476
}
426477

427478

clang/test/SemaCXX/type-traits-unsatisfied-diags.cpp

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -964,3 +964,91 @@ namespace is_aggregate {
964964

965965
static_assert(__is_aggregate(S7[10]));
966966
}
967+
968+
namespace is_abstract_tests {
969+
struct Abstract1 {
970+
virtual void fn1() = 0;
971+
};
972+
973+
struct Abstract2 {
974+
virtual void fn2() = 0;
975+
};
976+
977+
struct NonAbstract
978+
{
979+
virtual void f() {}
980+
};
981+
982+
// Multiple inheritance reports all abstract base classes that had their pure virtual functions overridden.
983+
struct Overrides : Abstract1, Abstract2, NonAbstract {
984+
void fn1() override {}
985+
void fn2() override {}
986+
};
987+
988+
static_assert(__is_abstract(Overrides));
989+
// expected-error@-1 {{static assertion failed due to requirement '__is_abstract(is_abstract_tests::Overrides)'}} \
990+
// expected-note@-1 {{'Overrides' is not abstract}} \
991+
// expected-note@-1 {{because it overrides all pure virtual functions from base class 'Abstract1'}} \
992+
// expected-note@-1 {{because it overrides all pure virtual functions from base class 'Abstract2'}} \
993+
994+
static_assert(__is_abstract(NonAbstract));
995+
// expected-error@-1 {{static assertion failed due to requirement '__is_abstract(is_abstract_tests::NonAbstract)'}} \
996+
// expected-note@-1 {{'NonAbstract' is not abstract}}
997+
998+
// Inheriting over two levels reports the last class only although the source of the pure virtual function
999+
// is the top-most base.
1000+
struct Derived : Abstract1 {
1001+
};
1002+
1003+
struct Derived2 : Derived {
1004+
void fn1() override {}
1005+
};
1006+
1007+
static_assert(__is_abstract(Derived2));
1008+
// expected-error@-1 {{static assertion failed due to requirement '__is_abstract(is_abstract_tests::Derived2)'}} \
1009+
// expected-note@-1 {{'Derived2' is not abstract}} \
1010+
// expected-note@-1 {{because it overrides all pure virtual functions from base class 'Derived'}} \
1011+
1012+
1013+
using I = int;
1014+
static_assert(__is_abstract(I));
1015+
// expected-error@-1 {{static assertion failed due to requirement '__is_abstract(int)'}} \
1016+
// expected-note@-1 {{'I' (aka 'int') is not abstract}} \
1017+
// expected-note@-1 {{because it is not a struct or class type}}
1018+
1019+
using Fty = void();
1020+
static_assert(__is_abstract(Fty));
1021+
// expected-error@-1 {{static assertion failed due to requirement '__is_abstract(void ())'}} \
1022+
// expected-note@-1 {{'Fty' (aka 'void ()') is not abstract}} \
1023+
// expected-note@-1 {{because it is a function type}} \
1024+
// expected-note@-1 {{because it is not a struct or class type}}
1025+
1026+
using Arr = int[3];
1027+
static_assert(__is_abstract(Arr));
1028+
// expected-error@-1 {{static assertion failed due to requirement '__is_abstract(int[3])'}} \
1029+
// expected-note@-1 {{'Arr' (aka 'int[3]') is not abstract}} \
1030+
// expected-note@-1 {{because it is an array type}} \
1031+
// expected-note@-1 {{because it is not a struct or class type}}
1032+
1033+
using Ref = int&;
1034+
static_assert(__is_abstract(Ref));
1035+
// expected-error@-1 {{static assertion failed due to requirement '__is_abstract(int &)'}} \
1036+
// expected-note@-1 {{'Ref' (aka 'int &') is not abstract}} \
1037+
// expected-note@-1 {{because it is a reference type}} \
1038+
// expected-note@-1 {{because it is not a struct or class type}}
1039+
1040+
using Ptr = int*;
1041+
static_assert(__is_abstract(Ptr));
1042+
// expected-error@-1 {{static assertion failed due to requirement '__is_abstract(int *)'}} \
1043+
// expected-note@-1 {{'Ptr' (aka 'int *') is not abstract}} \
1044+
// expected-note@-1 {{because it is a pointer type}} \
1045+
// expected-note@-1 {{because it is not a struct or class type}}
1046+
1047+
union U { int x; float y;};
1048+
static_assert(__is_abstract(U));
1049+
// expected-error@-1 {{static assertion failed due to requirement '__is_abstract(is_abstract_tests::U)'}} \
1050+
// expected-note@-1 {{'U' is not abstract}} \
1051+
// expected-note@-1 {{because it is a union type}} \
1052+
// expected-note@-1 {{because it is not a struct or class type}}
1053+
1054+
}

0 commit comments

Comments
 (0)