Skip to content
80 changes: 40 additions & 40 deletions clang/include/clang/Basic/Builtins.td
Original file line number Diff line number Diff line change
Expand Up @@ -1744,97 +1744,97 @@ def SyncSwapN : Builtin, SyncBuiltinsTemplate {
// C11 _Atomic operations for <stdatomic.h>.
def C11AtomicInit : AtomicBuiltin {
let Spellings = ["__c11_atomic_init"];
let Attributes = [CustomTypeChecking];
let Attributes = [CustomTypeChecking, Constexpr];
let Prototype = "void(...)";
}

def C11AtomicLoad : AtomicBuiltin {
let Spellings = ["__c11_atomic_load"];
let Attributes = [CustomTypeChecking];
let Attributes = [CustomTypeChecking, Constexpr];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm worried about changing the C11 atomic builtins for a C++26 feature; I think there are more changes needed as a result. For example, changing this to be constexpr means we now run the risk of accepting this code in C: https://godbolt.org/z/hc3oqYx6b

We likely are missing test coverage for this kind of thing in C, so I would recommend 1) add test coverage to this PR and if it breaks as a result of these changes, then 2) I would probably add some getLangOpts().CPlusPlus checks in the constant expression evaluator. We could invent new tablegen to say "this is constexpr only in C++", but it's not clear to me whether there will be enough builtins that need such functionality or not, but that's another (cleaner, but a heavier lift for a new contributor) option.

Hmm, but I just remembered that __has_constexpr_builtin (https://clang.llvm.org/docs/LanguageExtensions.html#has-constexpr-builtin) is a thing, so we may need that tablegen solution after all because otherwise we change the behavior here in confusing ways: https://godbolt.org/z/qGY575MGr FWIW, here's an example of some recent changes to tablegen that you could model your changes after: https://github.com/llvm/llvm-project/pull/91894/files

let Prototype = "void(...)";
}

def C11AtomicStore : AtomicBuiltin {
let Spellings = ["__c11_atomic_store"];
let Attributes = [CustomTypeChecking];
let Attributes = [CustomTypeChecking, Constexpr];
let Prototype = "void(...)";
}

def C11AtomicExchange : AtomicBuiltin {
let Spellings = ["__c11_atomic_exchange"];
let Attributes = [CustomTypeChecking];
let Attributes = [CustomTypeChecking, Constexpr];
let Prototype = "void(...)";
}

def C11AtomicCompareExchangeStrong : AtomicBuiltin {
let Spellings = ["__c11_atomic_compare_exchange_strong"];
let Attributes = [CustomTypeChecking];
let Attributes = [CustomTypeChecking, Constexpr];
let Prototype = "void(...)";
}

def C11AtomicCompareExchangeWeak : AtomicBuiltin {
let Spellings = ["__c11_atomic_compare_exchange_weak"];
let Attributes = [CustomTypeChecking];
let Attributes = [CustomTypeChecking, Constexpr];
let Prototype = "void(...)";
}

def C11AtomicFetchAdd : AtomicBuiltin {
let Spellings = ["__c11_atomic_fetch_add"];
let Attributes = [CustomTypeChecking];
let Attributes = [CustomTypeChecking, Constexpr];
let Prototype = "void(...)";
}

def C11AtomicFetchSub : AtomicBuiltin {
let Spellings = ["__c11_atomic_fetch_sub"];
let Attributes = [CustomTypeChecking];
let Attributes = [CustomTypeChecking, Constexpr];
let Prototype = "void(...)";
}

def C11AtomicFetchAnd : AtomicBuiltin {
let Spellings = ["__c11_atomic_fetch_and"];
let Attributes = [CustomTypeChecking];
let Attributes = [CustomTypeChecking, Constexpr];
let Prototype = "void(...)";
}

def C11AtomicFetchOr : AtomicBuiltin {
let Spellings = ["__c11_atomic_fetch_or"];
let Attributes = [CustomTypeChecking];
let Attributes = [CustomTypeChecking, Constexpr];
let Prototype = "void(...)";
}

def C11AtomicFetchXor : AtomicBuiltin {
let Spellings = ["__c11_atomic_fetch_xor"];
let Attributes = [CustomTypeChecking];
let Attributes = [CustomTypeChecking, Constexpr];
let Prototype = "void(...)";
}

def C11AtomicFetchNand : AtomicBuiltin {
let Spellings = ["__c11_atomic_fetch_nand"];
let Attributes = [CustomTypeChecking];
let Attributes = [CustomTypeChecking, Constexpr];
let Prototype = "void(...)";
}

def C11AtomicFetchMax : AtomicBuiltin {
let Spellings = ["__c11_atomic_fetch_max"];
let Attributes = [CustomTypeChecking];
let Attributes = [CustomTypeChecking, Constexpr];
let Prototype = "void(...)";
}

def C11AtomicFetchMin : AtomicBuiltin {
let Spellings = ["__c11_atomic_fetch_min"];
let Attributes = [CustomTypeChecking];
let Attributes = [CustomTypeChecking, Constexpr];
let Prototype = "void(...)";
}

def C11AtomicThreadFence : Builtin {
let Spellings = ["__c11_atomic_thread_fence"];
let Attributes = [NoThrow];
let Attributes = [NoThrow, Constexpr];
let Prototype = "void(int)";
}

def C11AtomicSignalFence : Builtin {
let Spellings = ["__c11_atomic_signal_fence"];
let Attributes = [NoThrow];
let Attributes = [NoThrow, Constexpr];
let Prototype = "void(int)";
}

Expand All @@ -1847,133 +1847,133 @@ def C11AtomicIsLockFree : Builtin {
// GNU atomic builtins.
def AtomicLoad : AtomicBuiltin {
let Spellings = ["__atomic_load"];
let Attributes = [CustomTypeChecking];
let Attributes = [CustomTypeChecking, Constexpr];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When removing the constexpr-ness from these functions in C, please also make sure __c11_atomic_is_lock_free is tested as well; that was already marked constexpr and that might be a bug.

let Prototype = "void(...)";
}

def AtomicLoadN : AtomicBuiltin {
let Spellings = ["__atomic_load_n"];
let Attributes = [CustomTypeChecking];
let Attributes = [CustomTypeChecking, Constexpr];
let Prototype = "void(...)";
}

def AtomicStore : AtomicBuiltin {
let Spellings = ["__atomic_store"];
let Attributes = [CustomTypeChecking];
let Attributes = [CustomTypeChecking, Constexpr];
let Prototype = "void(...)";
}

def AtomicStoreN : AtomicBuiltin {
let Spellings = ["__atomic_store_n"];
let Attributes = [CustomTypeChecking];
let Attributes = [CustomTypeChecking, Constexpr];
let Prototype = "void(...)";
}

def AtomicExchange : AtomicBuiltin {
let Spellings = ["__atomic_exchange"];
let Attributes = [CustomTypeChecking];
let Attributes = [CustomTypeChecking, Constexpr];
let Prototype = "void(...)";
}

def AtomicExchangeN : AtomicBuiltin {
let Spellings = ["__atomic_exchange_n"];
let Attributes = [CustomTypeChecking];
let Attributes = [CustomTypeChecking, Constexpr];
let Prototype = "void(...)";
}

def AtomicCompareExchange : AtomicBuiltin {
let Spellings = ["__atomic_compare_exchange"];
let Attributes = [CustomTypeChecking];
let Attributes = [CustomTypeChecking, Constexpr];
let Prototype = "void(...)";
}

def AtomicCompareExchangeN : AtomicBuiltin {
let Spellings = ["__atomic_compare_exchange_n"];
let Attributes = [CustomTypeChecking];
let Attributes = [CustomTypeChecking, Constexpr];
let Prototype = "void(...)";
}

def AtomicFetchAdd : AtomicBuiltin {
let Spellings = ["__atomic_fetch_add"];
let Attributes = [CustomTypeChecking];
let Attributes = [CustomTypeChecking, Constexpr];
let Prototype = "void(...)";
}

def AtomicFetchSub : AtomicBuiltin {
let Spellings = ["__atomic_fetch_sub"];
let Attributes = [CustomTypeChecking];
let Attributes = [CustomTypeChecking, Constexpr];
let Prototype = "void(...)";
}

def AtomicFetchAnd : AtomicBuiltin {
let Spellings = ["__atomic_fetch_and"];
let Attributes = [CustomTypeChecking];
let Attributes = [CustomTypeChecking, Constexpr];
let Prototype = "void(...)";
}

def AtomicFetchOr : AtomicBuiltin {
let Spellings = ["__atomic_fetch_or"];
let Attributes = [CustomTypeChecking];
let Attributes = [CustomTypeChecking, Constexpr];
let Prototype = "void(...)";
}

def AtomicFetchXor : AtomicBuiltin {
let Spellings = ["__atomic_fetch_xor"];
let Attributes = [CustomTypeChecking];
let Attributes = [CustomTypeChecking, Constexpr];
let Prototype = "void(...)";
}

def AtomicFetchNand : AtomicBuiltin {
let Spellings = ["__atomic_fetch_nand"];
let Attributes = [CustomTypeChecking];
let Attributes = [CustomTypeChecking, Constexpr];
let Prototype = "void(...)";
}

def AtomicAddFetch : AtomicBuiltin {
let Spellings = ["__atomic_add_fetch"];
let Attributes = [CustomTypeChecking];
let Attributes = [CustomTypeChecking, Constexpr];
let Prototype = "void(...)";
}

def AtomicSubFetch : AtomicBuiltin {
let Spellings = ["__atomic_sub_fetch"];
let Attributes = [CustomTypeChecking];
let Attributes = [CustomTypeChecking, Constexpr];
let Prototype = "void(...)";
}

def AtomicAndFetch : AtomicBuiltin {
let Spellings = ["__atomic_and_fetch"];
let Attributes = [CustomTypeChecking];
let Attributes = [CustomTypeChecking, Constexpr];
let Prototype = "void(...)";
}

def AtomicOrFetch : AtomicBuiltin {
let Spellings = ["__atomic_or_fetch"];
let Attributes = [CustomTypeChecking];
let Attributes = [CustomTypeChecking, Constexpr];
let Prototype = "void(...)";
}

def AtomicXorFetch : AtomicBuiltin {
let Spellings = ["__atomic_xor_fetch"];
let Attributes = [CustomTypeChecking];
let Attributes = [CustomTypeChecking, Constexpr];
let Prototype = "void(...)";
}

def AtomicMaxFetch : AtomicBuiltin {
let Spellings = ["__atomic_max_fetch"];
let Attributes = [CustomTypeChecking];
let Attributes = [CustomTypeChecking, Constexpr];
let Prototype = "void(...)";
}

def AtomicMinFetch : AtomicBuiltin {
let Spellings = ["__atomic_min_fetch"];
let Attributes = [CustomTypeChecking];
let Attributes = [CustomTypeChecking, Constexpr];
let Prototype = "void(...)";
}

def AtomicNandFetch : AtomicBuiltin {
let Spellings = ["__atomic_nand_fetch"];
let Attributes = [CustomTypeChecking];
let Attributes = [CustomTypeChecking, Constexpr];
let Prototype = "void(...)";
}

Expand All @@ -1991,7 +1991,7 @@ def AtomicClear : Builtin {

def AtomicThreadFence : Builtin {
let Spellings = ["__atomic_thread_fence"];
let Attributes = [NoThrow];
let Attributes = [NoThrow, Constexpr];
let Prototype = "void(int)";
}

Expand All @@ -2003,7 +2003,7 @@ def ScopedAtomicThreadFence : Builtin {

def AtomicSignalFence : Builtin {
let Spellings = ["__atomic_signal_fence"];
let Attributes = [NoThrow];
let Attributes = [NoThrow, Constexpr];
let Prototype = "void(int)";
}

Expand Down
Loading
Loading