Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,7 @@ Bug Fixes to AST Handling

Miscellaneous Bug Fixes
^^^^^^^^^^^^^^^^^^^^^^^
- Fixed missing diagnostics of ``diagnose_if`` on templates involved in initialization. (#GH160776)

Miscellaneous Clang Crashes Fixed
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
6 changes: 3 additions & 3 deletions clang/lib/Sema/SemaInit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7539,7 +7539,7 @@ PerformConstructorInitialization(Sema &S,

// Only check access if all of that succeeded.
S.CheckConstructorAccess(Loc, Constructor, Step.Function.FoundDecl, Entity);
if (S.DiagnoseUseOfDecl(Step.Function.FoundDecl, Loc))
if (S.DiagnoseUseOfOverloadedDecl(Constructor, Loc))
return ExprError();

if (const ArrayType *AT = S.Context.getAsArrayType(Entity.getType()))
Expand Down Expand Up @@ -8092,7 +8092,7 @@ ExprResult InitializationSequence::Perform(Sema &S,

S.CheckConstructorAccess(Kind.getLocation(), Constructor, FoundFn,
Entity);
if (S.DiagnoseUseOfDecl(FoundFn, Kind.getLocation()))
if (S.DiagnoseUseOfOverloadedDecl(Constructor, Kind.getLocation()))
return ExprError();

CastKind = CK_ConstructorConversion;
Expand All @@ -8102,7 +8102,7 @@ ExprResult InitializationSequence::Perform(Sema &S,
CXXConversionDecl *Conversion = cast<CXXConversionDecl>(Fn);
S.CheckMemberOperatorAccess(Kind.getLocation(), CurInit.get(), nullptr,
FoundFn);
if (S.DiagnoseUseOfDecl(FoundFn, Kind.getLocation()))
if (S.DiagnoseUseOfOverloadedDecl(Conversion, Kind.getLocation()))
return ExprError();

CurInit = S.BuildCXXMemberCallExpr(CurInit.get(), FoundFn, Conversion,
Expand Down
2 changes: 1 addition & 1 deletion clang/test/Parser/cxx0x-lambda-expressions.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -verify=expected,cxx14ext,cxx17ext,cxx20ext,cxx23ext -std=c++03 -Wno-c99-designator %s -Wno-c++11-extensions
// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -verify=expected,cxx14ext,cxx17ext,cxx20ext,cxx23ext -std=c++03 -Wno-c99-designator %s -Wno-c++11-extensions -Wno-local-type-template-args
// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -verify=expected,cxx14ext,cxx17ext,cxx20ext,cxx23ext -std=c++11 -Wno-c99-designator %s
// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -verify=expected,cxx17ext,cxx20ext,cxx23ext -std=c++14 -Wno-c99-designator %s
// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -verify=expected,cxx20ext,cxx23ext -std=c++17 -Wno-c99-designator %s
Expand Down
27 changes: 27 additions & 0 deletions clang/test/SemaCXX/diagnose_if.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// RUN: %clang_cc1 %s -verify -fno-builtin -std=c++14
// RUN: %clang_cc1 %s -verify -fno-builtin -std=c++20 -verify=expected,cxx20
// RUN: %clang_cc1 %s -verify -fno-builtin -std=c++14 -fexperimental-new-constant-interpreter
// RUN: %clang_cc1 %s -verify -fno-builtin -std=c++20 -verify=expected,cxx20 -fexperimental-new-constant-interpreter

#define _diagnose_if(...) __attribute__((diagnose_if(__VA_ARGS__)))

Expand Down Expand Up @@ -665,3 +667,28 @@ void run() {
switch (constexpr Foo i = 2) { default: break; } // expected-error{{oh no}}
}
}

namespace GH160776 {

struct ConstructorTemplate {
template <class T>
explicit ConstructorTemplate(T x)
_diagnose_if(sizeof(T) == sizeof(char), "oh no", "error") {} // expected-note {{diagnose_if}}

template <class T>
#if __cplusplus >= 202002L
requires (sizeof(T) == 1) // cxx20-note {{evaluated to false}}
#endif
operator T() _diagnose_if(sizeof(T) == sizeof(char), "oh no", "error") { // expected-note {{diagnose_if}} \
// cxx20-note {{constraints not satisfied}}
return T{};
}
};

void run() {
ConstructorTemplate x('1'); // expected-error {{oh no}}
char y = x; // expected-error {{oh no}}
int z = x; // cxx20-error {{no viable conversion}}
}

}
30 changes: 23 additions & 7 deletions clang/test/SemaCXX/lambda-expressions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,8 @@ namespace PR12031 {
void f(int i, X x);
void g() {
const int v = 10;
f(v, [](){});
f(v, [](){}); // cxx03-warning {{template argument uses local type}} \
// cxx03-note {{while substituting}}
}
}

Expand Down Expand Up @@ -572,26 +573,37 @@ namespace PR27994 {
struct A { template <class T> A(T); };

template <class T>
struct B {
struct B { // #PR27994_B
int x;
A a = [&] { int y = x; };
A b = [&] { [&] { [&] { int y = x; }; }; };
A d = [&](auto param) { int y = x; }; // cxx03-cxx11-error {{'auto' not allowed in lambda parameter}}
A e = [&](auto param) { [&] { [&](auto param2) { int y = x; }; }; }; // cxx03-cxx11-error 2 {{'auto' not allowed in lambda parameter}}
A a = [&] { int y = x; }; // cxx03-warning {{template argument uses unnamed type}} \
// cxx03-note {{while substituting}} cxx03-note {{unnamed type used}}
A b = [&] { [&] { [&] { int y = x; }; }; }; // cxx03-warning {{template argument uses unnamed type}} \
// cxx03-note {{while substituting}} cxx03-note {{unnamed type used}}
A d = [&](auto param) { int y = x; }; // cxx03-cxx11-error {{'auto' not allowed in lambda parameter}} \
// cxx03-warning {{template argument uses unnamed type}} \
// cxx03-note {{while substituting}} cxx03-note {{unnamed type used}}
A e = [&](auto param) { [&] { [&](auto param2) { int y = x; }; }; }; // cxx03-cxx11-error 2 {{'auto' not allowed in lambda parameter}} \
// cxx03-warning {{template argument uses unnamed type}} \
// cxx03-note {{while substituting}} cxx03-note {{unnamed type used}}
};

B<int> b;
// cxx03-note@#PR27994_B 4{{in instantiation of default member initializer}}
// cxx03-note@-2 4{{in evaluation of exception}}

template <class T> struct C {
struct D {
// cxx03-note@-1 {{in instantiation of default member initializer}}
int x;
A f = [&] { int y = x; };
A f = [&] { int y = x; }; // cxx03-warning {{template argument uses unnamed type}} \
// cxx03-note {{while substituting}} cxx03-note {{unnamed type used}}
};
};

int func() {
C<int> a;
decltype(a)::D b;
// cxx03-note@-1 {{in evaluation of exception}}
}
}

Expand All @@ -606,8 +618,12 @@ struct S1 {

void foo1() {
auto s0 = S1([name=]() {}); // expected-error {{expected expression}}
// cxx03-warning@-1 {{template argument uses local type}} \
// cxx03-note@-1 {{while substituting deduced template arguments}}
auto s1 = S1([name=name]() {}); // expected-error {{use of undeclared identifier 'name'; did you mean 'name1'?}}
// cxx03-cxx11-warning@-1 {{initialized lambda captures are a C++14 extension}}
// cxx03-warning@-2 {{template argument uses local type}} \
// cxx03-note@-2 {{while substituting deduced template arguments}}
}
}

Expand Down