Skip to content

Commit c1f4b04

Browse files
Merge branch 'main' into users/matthias-springer/get_array_attr_overload
2 parents cc99086 + 23f09fd commit c1f4b04

File tree

70 files changed

+1600
-670
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+1600
-670
lines changed

clang/docs/HIPSupport.rst

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,57 @@ Example Usage
412412
__host__ __device__ int Four(void) __attribute__((weak, alias("_Z6__Fourv")));
413413
__host__ __device__ float Four(float f) __attribute__((weak, alias("_Z6__Fourf")));
414414

415+
C++17 Class Template Argument Deduction (CTAD) Support
416+
======================================================
417+
418+
Clang supports C++17 Class Template Argument Deduction (CTAD) in both host and
419+
device code for HIP. This allows you to omit template arguments when creating
420+
class template instances, letting the compiler deduce them from constructor
421+
arguments.
422+
423+
.. code-block:: c++
424+
425+
#include <tuple>
426+
427+
__host__ __device__ void func() {
428+
std::tuple<int, int> t = std::tuple(1, 1);
429+
}
430+
431+
In the above example, ``std::tuple(1, 1)`` automatically deduces the type to be
432+
``std::tuple<int, int>``.
433+
434+
Deduction Guides
435+
----------------
436+
437+
User-defined deduction guides are also supported. Since deduction guides are not
438+
executable code and only participate in type deduction, they semantically behave
439+
as ``__host__ __device__``. This ensures they are available for deduction in both
440+
host and device contexts, and CTAD continues to respect any constraints on the
441+
corresponding constructors in the usual C++ way.
442+
443+
.. code-block:: c++
444+
445+
template <typename T>
446+
struct MyType {
447+
T value;
448+
__device__ MyType(T v) : value(v) {}
449+
};
450+
451+
MyType(float) -> MyType<double>;
452+
453+
__device__ void deviceFunc() {
454+
MyType m(1.0f); // Deduces MyType<double>
455+
}
456+
457+
.. note::
458+
459+
Explicit HIP target attributes such as ``__host__`` or ``__device__``
460+
are currently only permitted on deduction guides when both are present
461+
(``__host__ __device__``). This usage is deprecated and will be rejected
462+
in a future version of Clang; prefer omitting HIP target attributes on
463+
deduction guides entirely. Clang treats all deduction guides as if they
464+
were ``__host__ __device__``, so ``__host__``-only, ``__device__``-only,
465+
or ``__global__`` deduction guides are rejected as ill-formed.
415466

416467
Host and Device Attributes of Default Destructors
417468
===================================================

clang/docs/ReleaseNotes.rst

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,23 @@ RISC-V Support
663663
CUDA/HIP Language Changes
664664
^^^^^^^^^^^^^^^^^^^^^^^^^
665665

666+
- Clang now supports C++17 Class Template Argument Deduction (CTAD) in CUDA/HIP
667+
device code by treating deduction guides as if they were ``__host__ __device__``.
668+
669+
- Clang avoids ambiguous CTAD in CUDA/HIP by not synthesizing duplicate implicit
670+
deduction guides when ``__host__`` and ``__device__`` constructors differ only
671+
in CUDA target attributes (same signature and constraints).
672+
673+
- Clang diagnoses CUDA/HIP deduction guides that are annotated as host-only,
674+
device-only, or ``__global__`` as errors. Explicit ``__host__ __device__``
675+
deduction guides remain accepted for now but are deprecated and will be
676+
rejected in a future version of Clang; deduction guides do not participate
677+
in code generation and are treated as implicitly host+device.
678+
679+
- Clang preserves distinct implicit deduction guides for constructors that differ
680+
by constraints, so constraint-based CTAD works in CUDA/HIP device code as in
681+
standard C++.
682+
666683
CUDA Support
667684
^^^^^^^^^^^^
668685

clang/include/clang/AST/PrettyPrinter.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
#include "clang/Basic/LLVM.h"
1717
#include "clang/Basic/LangOptions.h"
18+
#include "llvm/ADT/STLForwardCompat.h"
1819

1920
namespace clang {
2021

@@ -55,14 +56,15 @@ class PrintingCallbacks {
5556
/// This type is intended to be small and suitable for passing by value.
5657
/// It is very frequently copied.
5758
struct PrintingPolicy {
58-
enum SuppressInlineNamespaceMode : uint8_t { None, Redundant, All };
59+
enum class SuppressInlineNamespaceMode : uint8_t { None, Redundant, All };
5960

6061
/// Create a default printing policy for the specified language.
6162
PrintingPolicy(const LangOptions &LO)
6263
: Indentation(2), SuppressSpecifiers(false),
6364
SuppressTagKeyword(LO.CPlusPlus), IncludeTagDefinition(false),
6465
SuppressScope(false), SuppressUnwrittenScope(false),
65-
SuppressInlineNamespace(SuppressInlineNamespaceMode::Redundant),
66+
SuppressInlineNamespace(
67+
llvm::to_underlying(SuppressInlineNamespaceMode::Redundant)),
6668
SuppressInitializers(false), ConstantArraySizeAsWritten(false),
6769
AnonymousTagLocations(true), SuppressStrongLifetime(false),
6870
SuppressLifetimeQualifiers(false),

clang/include/clang/Basic/Builtins.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,12 @@ struct Info {
9595
///
9696
/// Must be provided the `Shard` for this `Info` object.
9797
std::string getName(const InfosShard &Shard) const;
98+
99+
// Builtin non-null attribute modes.
100+
// NonOptimizing: attaches Clang's `_Nonnull` type qualifier to parameters.
101+
// Optimizing: emits the classic GNU-style `nonnull` attribute for
102+
// optimization.
103+
enum class NonNullMode { NonOptimizing, Optimizing };
98104
};
99105

100106
/// A constexpr function to construct an infos array from X-macros.
@@ -393,6 +399,11 @@ class Context {
393399
bool performsCallback(unsigned ID,
394400
llvm::SmallVectorImpl<int> &Encoding) const;
395401

402+
/// Return true if this builtin has parameters that must be non-null.
403+
/// The parameter indices are appended into 'Indxs'.
404+
bool isNonNull(unsigned ID, llvm::SmallVectorImpl<int> &Indxs,
405+
Info::NonNullMode &Mode) const;
406+
396407
/// Return true if this function has no side effects and doesn't
397408
/// read memory, except for possibly errno or raising FP exceptions.
398409
///

clang/include/clang/Basic/Builtins.td

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3119,104 +3119,105 @@ def StrLen : LibBuiltin<"string.h"> {
31193119
// FIXME: This list is incomplete.
31203120
def Printf : LibBuiltin<"stdio.h"> {
31213121
let Spellings = ["printf"];
3122-
let Attributes = [PrintfFormat<0>];
3122+
let Attributes = [PrintfFormat<0>, NonNull<NonOptimizing, [0]>];
31233123
let Prototype = "int(char const*, ...)";
31243124
}
31253125

31263126
// FIXME: The builtin and library function should have the same signature.
31273127
def BuiltinPrintf : Builtin {
31283128
let Spellings = ["__builtin_printf"];
3129-
let Attributes = [NoThrow, PrintfFormat<0>, FunctionWithBuiltinPrefix];
3129+
let Attributes = [NoThrow, PrintfFormat<0>, FunctionWithBuiltinPrefix,
3130+
NonNull<NonOptimizing, [0]>];
31303131
let Prototype = "int(char const* restrict, ...)";
31313132
}
31323133

31333134
def FPrintf : LibBuiltin<"stdio.h"> {
31343135
let Spellings = ["fprintf"];
3135-
let Attributes = [NoThrow, PrintfFormat<1>];
3136+
let Attributes = [NoThrow, PrintfFormat<1>, NonNull<NonOptimizing, [0, 1]>];
31363137
let Prototype = "int(FILE* restrict, char const* restrict, ...)";
31373138
let AddBuiltinPrefixedAlias = 1;
31383139
}
31393140

31403141
def SnPrintf : LibBuiltin<"stdio.h"> {
31413142
let Spellings = ["snprintf"];
3142-
let Attributes = [NoThrow, PrintfFormat<2>];
3143+
let Attributes = [NoThrow, PrintfFormat<2>, NonNull<NonOptimizing, [2]>];
31433144
let Prototype = "int(char* restrict, size_t, char const* restrict, ...)";
31443145
let AddBuiltinPrefixedAlias = 1;
31453146
}
31463147

31473148
def SPrintf : LibBuiltin<"stdio.h"> {
31483149
let Spellings = ["sprintf"];
3149-
let Attributes = [NoThrow, PrintfFormat<1>];
3150+
let Attributes = [NoThrow, PrintfFormat<1>, NonNull<NonOptimizing, [0, 1]>];
31503151
let Prototype = "int(char* restrict, char const* restrict, ...)";
31513152
let AddBuiltinPrefixedAlias = 1;
31523153
}
31533154

31543155
def VPrintf : LibBuiltin<"stdio.h"> {
31553156
let Spellings = ["vprintf"];
3156-
let Attributes = [NoThrow, VPrintfFormat<0>];
3157+
let Attributes = [NoThrow, VPrintfFormat<0>, NonNull<NonOptimizing, [0]>];
31573158
let Prototype = "int(char const* restrict, __builtin_va_list)";
31583159
let AddBuiltinPrefixedAlias = 1;
31593160
}
31603161

31613162
def VfPrintf : LibBuiltin<"stdio.h"> {
31623163
let Spellings = ["vfprintf"];
3163-
let Attributes = [NoThrow, VPrintfFormat<1>];
3164+
let Attributes = [NoThrow, VPrintfFormat<1>, NonNull<NonOptimizing, [0, 1]>];
31643165
let Prototype = "int(FILE* restrict, char const* restrict, __builtin_va_list)";
31653166
let AddBuiltinPrefixedAlias = 1;
31663167
}
31673168

31683169
def VsnPrintf : LibBuiltin<"stdio.h"> {
31693170
let Spellings = ["vsnprintf"];
3170-
let Attributes = [NoThrow, VPrintfFormat<2>];
3171+
let Attributes = [NoThrow, VPrintfFormat<2>, NonNull<NonOptimizing, [2]>];
31713172
let Prototype = "int(char* restrict, size_t, char const* restrict, __builtin_va_list)";
31723173
let AddBuiltinPrefixedAlias = 1;
31733174
}
31743175

31753176
def VsPrintf : LibBuiltin<"stdio.h"> {
31763177
let Spellings = ["vsprintf"];
3177-
let Attributes = [NoThrow, VPrintfFormat<1>];
3178+
let Attributes = [NoThrow, VPrintfFormat<1>, NonNull<NonOptimizing, [0, 1]>];
31783179
let Prototype = "int(char* restrict, char const* restrict, __builtin_va_list)";
31793180
let AddBuiltinPrefixedAlias = 1;
31803181
}
31813182

31823183
def Scanf : LibBuiltin<"stdio.h"> {
31833184
let Spellings = ["scanf"];
3184-
let Attributes = [ScanfFormat<0>];
3185+
let Attributes = [ScanfFormat<0>, NonNull<NonOptimizing, [0]>];
31853186
let Prototype = "int(char const* restrict, ...)";
31863187
let AddBuiltinPrefixedAlias = 1;
31873188
}
31883189

31893190
def FScanf : LibBuiltin<"stdio.h"> {
31903191
let Spellings = ["fscanf"];
3191-
let Attributes = [ScanfFormat<1>];
3192+
let Attributes = [ScanfFormat<1>, NonNull<NonOptimizing, [0, 1]>];
31923193
let Prototype = "int(FILE* restrict, char const* restrict, ...)";
31933194
let AddBuiltinPrefixedAlias = 1;
31943195
}
31953196

31963197
def SScanf : LibBuiltin<"stdio.h"> {
31973198
let Spellings = ["sscanf"];
3198-
let Attributes = [ScanfFormat<1>];
3199+
let Attributes = [ScanfFormat<1>, NonNull<NonOptimizing, [0, 1]>];
31993200
let Prototype = "int(char const* restrict, char const* restrict, ...)";
32003201
let AddBuiltinPrefixedAlias = 1;
32013202
}
32023203

32033204
def VScanf : LibBuiltin<"stdio.h"> {
32043205
let Spellings = ["vscanf"];
3205-
let Attributes = [VScanfFormat<0>];
3206+
let Attributes = [VScanfFormat<0>, NonNull<NonOptimizing, [0]>];
32063207
let Prototype = "int(char const* restrict, __builtin_va_list)";
32073208
let AddBuiltinPrefixedAlias = 1;
32083209
}
32093210

32103211
def VFScanf : LibBuiltin<"stdio.h"> {
32113212
let Spellings = ["vfscanf"];
3212-
let Attributes = [VScanfFormat<1>];
3213+
let Attributes = [VScanfFormat<1>, NonNull<NonOptimizing, [0, 1]>];
32133214
let Prototype = "int(FILE* restrict, char const* restrict, __builtin_va_list)";
32143215
let AddBuiltinPrefixedAlias = 1;
32153216
}
32163217

32173218
def VSScanf : LibBuiltin<"stdio.h"> {
32183219
let Spellings = ["vsscanf"];
3219-
let Attributes = [VScanfFormat<1>];
3220+
let Attributes = [VScanfFormat<1>, NonNull<NonOptimizing, [0, 1]>];
32203221
let Prototype = "int(char const* restrict, char const* restrict, __builtin_va_list)";
32213222
let AddBuiltinPrefixedAlias = 1;
32223223
}

clang/include/clang/Basic/BuiltinsBase.td

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,17 @@ def Const : Attribute<"c">;
3232
def NoThrow : Attribute<"n">;
3333
def Pure : Attribute<"U">;
3434
def ReturnsTwice : Attribute<"j">;
35-
// FIXME: gcc has nonnull
35+
36+
class NonNullOptMode<int mode> {
37+
int value = mode;
38+
}
39+
40+
def NonOptimizing : NonNullOptMode<0>;
41+
def Optimizing : NonNullOptMode<1>;
42+
43+
class NonNull<NonNullOptMode Mode, list<int> Is> : MultiIndexAttribute<"N:" # Mode.value # ":", Is> {
44+
int optMode = Mode.value;
45+
}
3646

3747
// builtin-specific attributes
3848
// ---------------------------

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2769,6 +2769,14 @@ def err_deduction_guide_name_not_class_template : Error<
27692769
"cannot specify deduction guide for "
27702770
"%select{<error>|function template|variable template|alias template|"
27712771
"template template parameter|concept|dependent template name}0 %1">;
2772+
def err_deduction_guide_target_attr : Error<
2773+
"in CUDA/HIP, deduction guides may only be annotated with "
2774+
"'__host__ __device__'; '__host__'-only, '__device__'-only, or "
2775+
"'__global__' deduction guides are not allowed">;
2776+
def warn_deduction_guide_target_attr_deprecated : Warning<
2777+
"use of CUDA/HIP target attributes on deduction guides is deprecated; "
2778+
"they will be rejected in a future version of Clang">,
2779+
InGroup<DeprecatedAttributes>;
27722780
def err_deduction_guide_wrong_scope : Error<
27732781
"deduction guide must be declared in the same scope as template %q0">;
27742782
def err_deduction_guide_defines_function : Error<

clang/lib/AST/Decl.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1753,9 +1753,11 @@ void NamedDecl::printNestedNameSpecifier(raw_ostream &OS,
17531753
// Suppress inline namespace if it doesn't make the result ambiguous.
17541754
if (Ctx->isInlineNamespace() && NameInScope) {
17551755
if (P.SuppressInlineNamespace ==
1756-
PrintingPolicy::SuppressInlineNamespaceMode::All ||
1756+
llvm::to_underlying(
1757+
PrintingPolicy::SuppressInlineNamespaceMode::All) ||
17571758
(P.SuppressInlineNamespace ==
1758-
PrintingPolicy::SuppressInlineNamespaceMode::Redundant &&
1759+
llvm::to_underlying(
1760+
PrintingPolicy::SuppressInlineNamespaceMode::Redundant) &&
17591761
cast<NamespaceDecl>(Ctx)->isRedundantInlineQualifierFor(
17601762
NameInScope))) {
17611763
continue;

clang/lib/ASTMatchers/ASTMatchersInternal.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -654,9 +654,9 @@ bool HasNameMatcher::matchesNodeFullSlow(const NamedDecl &Node) const {
654654

655655
PrintingPolicy Policy = Node.getASTContext().getPrintingPolicy();
656656
Policy.SuppressUnwrittenScope = SkipUnwritten;
657-
Policy.SuppressInlineNamespace =
657+
Policy.SuppressInlineNamespace = llvm::to_underlying(
658658
SkipUnwritten ? PrintingPolicy::SuppressInlineNamespaceMode::All
659-
: PrintingPolicy::SuppressInlineNamespaceMode::None;
659+
: PrintingPolicy::SuppressInlineNamespaceMode::None);
660660
Node.printQualifiedName(OS, Policy);
661661

662662
const StringRef FullName = OS.str();

clang/lib/Analysis/ThreadSafety.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#include "llvm/ADT/SmallVector.h"
4444
#include "llvm/ADT/StringRef.h"
4545
#include "llvm/Support/Allocator.h"
46+
#include "llvm/Support/Casting.h"
4647
#include "llvm/Support/ErrorHandling.h"
4748
#include "llvm/Support/TrailingObjects.h"
4849
#include "llvm/Support/raw_ostream.h"
@@ -2820,6 +2821,12 @@ void ThreadSafetyAnalyzer::runAnalysis(AnalysisDeclContext &AC) {
28202821
case CFGElement::AutomaticObjectDtor: {
28212822
CFGAutomaticObjDtor AD = BI.castAs<CFGAutomaticObjDtor>();
28222823
const auto *DD = AD.getDestructorDecl(AC.getASTContext());
2824+
// Function parameters as they are constructed in caller's context and
2825+
// the CFG does not contain the ctors. Ignore them as their
2826+
// capabilities cannot be analysed because of this missing
2827+
// information.
2828+
if (isa_and_nonnull<ParmVarDecl>(AD.getVarDecl()))
2829+
break;
28232830
if (!DD || !DD->hasAttrs())
28242831
break;
28252832

0 commit comments

Comments
 (0)