Skip to content
Closed
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
9 changes: 0 additions & 9 deletions clang/include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -1264,15 +1264,6 @@ def Const : InheritableAttr {
let SimpleHandler = 1;
}

def Realtime : InheritableAttr {
let Spellings = [CXX11<"clang", "realtime">,
C23<"clang", "realtime">,
GCC<"realtime">];
let Subjects = SubjectList<[Function]>;
let Documentation = [Undocumented];
let SimpleHandler = 1;
}

def ConstInit : InheritableAttr {
// This attribute does not have a C [[]] spelling because it requires the
// CPlusPlus language option.
Expand Down
7 changes: 0 additions & 7 deletions clang/include/clang/Basic/AttrDocs.td
Original file line number Diff line number Diff line change
Expand Up @@ -7619,13 +7619,6 @@ its underlying representation to be a WebAssembly ``funcref``.
}];
}

def RealtimeDocs : Documentation {
let Category = DocCatFunction;
let Heading = "Realtime Attribute";
let Content = [{
}];
}

def PreferredTypeDocumentation : Documentation {
let Category = DocCatField;
let Content = [{
Expand Down
8 changes: 6 additions & 2 deletions clang/lib/CodeGen/CGCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2384,8 +2384,6 @@ void CodeGenModule::ConstructAttributeList(StringRef Name,
FuncAttrs.addAttribute(llvm::Attribute::NoDuplicate);
if (TargetDecl->hasAttr<ConvergentAttr>())
FuncAttrs.addAttribute(llvm::Attribute::Convergent);
if (TargetDecl->hasAttr<RealtimeAttr>())
FuncAttrs.addAttribute(llvm::Attribute::Realtime);

if (const FunctionDecl *Fn = dyn_cast<FunctionDecl>(TargetDecl)) {
AddAttributesFromFunctionProtoType(
Expand All @@ -2406,6 +2404,12 @@ void CodeGenModule::ConstructAttributeList(StringRef Name,
FuncAttrs.addAttribute(llvm::Attribute::NoReturn);
NBA = Fn->getAttr<NoBuiltinAttr>();
}

for (const FunctionEffectWithCondition& Fe : Fn->getFunctionEffects()) {
if (Fe.Effect.kind() == FunctionEffect::Kind::NonBlocking) {
FuncAttrs.addAttribute(llvm::Attribute::NonBlocking);
}
}
Copy link
Owner Author

Choose a reason for hiding this comment

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

LOOK HERE!

In the past, all we had to do was look at if the attribute existed on the function. Now, doug uses these "function effects".

Please dig into the FunctionEffects class, and it's related classes and make sure you agree what I'm doing here is valid.

Try running a test program with a function marked [[clang::nonblocking]] [[clang::nonblocking(false)]] [[clang::nonblocking(true)]]

Just in writing this comment, I discovered this does not catch [[clang::blocking(false)]] which it should. This may be something you could fix while you're in here

Copy link
Owner Author

Choose a reason for hiding this comment

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

Ok, [[clang::blocking(false)]] is now disallowed by the compiler, so I believe this code to be correct as written. The effect will "resolve" at this point to either blocking or nonblocking. [[noblocking(false)] resolves to blocking and so we never trip this conditional.

}

if (isa<FunctionDecl>(TargetDecl) || isa<VarDecl>(TargetDecl)) {
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/CodeGen/CodeGenFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1592,7 +1592,7 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn,
insertCallAtFunctionEntryPoint(Fn, "radsan_off");
}

if (Fn->hasFnAttribute(llvm::Attribute::Realtime)) {
if (Fn->hasFnAttribute(llvm::Attribute::NonBlocking)) {
insertCallAtFunctionEntryPoint(Fn, "radsan_realtime_enter");
}
}
Expand All @@ -1605,7 +1605,7 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn,
insertCallAtAllFunctionExitPoints(Fn, "radsan_on");
}

if (Fn->hasFnAttribute(llvm::Attribute::Realtime)) {
if (Fn->hasFnAttribute(llvm::Attribute::NonBlocking)) {
insertCallAtAllFunctionExitPoints(Fn, "radsan_realtime_exit");
}
}
Expand Down
2 changes: 1 addition & 1 deletion compiler-rt/lib/radsan/radsan.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ RADSAN_EXPORT void radsan_realtime_exit();

Example:

[[clang::realtime]] float process (float x)
float process (float x) [[clang::nonblocking]]
{
auto const y = 2.0f * x;

Expand Down
3 changes: 2 additions & 1 deletion compiler-rt/lib/radsan/tests/radsan_test_utilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
namespace radsan_testing {

template <typename Function>
[[clang::realtime]] void realtimeInvoke(Function &&func) {
void realtimeInvoke(Function &&func) [[clang::nonblocking]]
Copy link
Owner Author

Choose a reason for hiding this comment

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

Notice we must now have this after the declaration, before the declaration throws a warning and does not work

Choose a reason for hiding this comment

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

Nice - yep, this is good

{
std::forward<Function>(func)();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ void violationLock(pthread_mutex_t& Mutex) {
pthread_mutex_lock(&Mutex);
}

[[clang::realtime]] void process(pthread_mutex_t& Mutex) {
void process(pthread_mutex_t& Mutex) [[clang::nonblocking]] {
bypassedLock(Mutex);
bypassedUnlock(Mutex);

Expand Down
2 changes: 1 addition & 1 deletion compiler-rt/test/radsan/TestCases/test_continue_mode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ void freeViolation(void* Ptr) {
free(Ptr);
}

[[clang::realtime]] void process() {
void process() [[clang::nonblocking]] {
void* Ptr = mallocViolation();
freeViolation(Ptr);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// UNSUPPORTED: ios

// Intent: Ensure that a no_sanitize attribute has no impact
// if not in a [[clang::realtime]] function
// if not in a [[clang::nonblocking]] function

#include <stdio.h>
#include <stdlib.h>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// RUN: %run %t 2>&1 | FileCheck %s
// UNSUPPORTED: ios

// Intent: Ensure that no_sanitize and [[clang::realtime]]
// Intent: Ensure that no_sanitize and [[clang::nonblocking]]
// have no impact if -fsanitize=realtime is not used

#include <stdio.h>
Expand All @@ -13,7 +13,7 @@ void noSanitizeFree(void* Ptr) {
free(Ptr);
}

[[clang::realtime]] void violation() {
void violation() [[clang::nonblocking]]{
void* Ptr = malloc(2);
noSanitizeFree(Ptr);
}
Expand Down
4 changes: 2 additions & 2 deletions compiler-rt/test/radsan/TestCases/test_radsan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
// RUN: not %run %t 2>&1 | FileCheck %s
// UNSUPPORTED: ios

// Intent: Ensure that an intercepted call in a [[clang::realtime]] function
// Intent: Ensure that an intercepted call in a [[clang::nonblocking]] function
// is flagged as an error. Basic smoke test.

#include <stdlib.h>

[[clang::realtime]] void violation() {
void violation() [[clang::nonblocking]]{
void* Ptr = malloc(2);
}

Expand Down
4 changes: 2 additions & 2 deletions compiler-rt/test/radsan/TestCases/test_radsan_inactive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
// RUN: %run %t 2>&1 | FileCheck %s
// UNSUPPORTED: ios

// Intent: Ensure [[clang::realtime]] has no impact if -fsanitize=realtime is not used
// Intent: Ensure [[clang::nonblocking]] has no impact if -fsanitize=realtime is not used

#include <stdio.h>
#include <stdlib.h>

// In this test, we don't use the -fsanitize=realtime flag, so nothing
// should happen here
[[clang::realtime]] void violation() {
void violation() [[clang::nonblocking]] {
void* Ptr = malloc(2);
}

Expand Down
2 changes: 1 addition & 1 deletion llvm/docs/LangRef.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2139,7 +2139,7 @@ example:
for this function.
``nosanitize_realtime``
This attribute indicates that SanitizerRealtime is disabled for this
function. If called from a function marked ``clang::realtime``, no
function. If called from a function marked ``clang::nonblocking``, no
errors that would normally be reported by SanitizerRealtime will be
reported.
``null_pointer_is_valid``
Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/Bitcode/LLVMBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -744,7 +744,7 @@ enum AttributeKindCodes {
ATTR_KIND_CORO_ONLY_DESTROY_WHEN_COMPLETE = 90,
ATTR_KIND_DEAD_ON_UNWIND = 91,
ATTR_KIND_RANGE = 92,
ATTR_KIND_REALTIME = 93,
ATTR_KIND_NONBLOCKING = 93,
ATTR_KIND_NO_SANITIZE_REALTIME = 94,
};

Expand Down
4 changes: 2 additions & 2 deletions llvm/include/llvm/IR/Attributes.td
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,8 @@ def ReadNone : EnumAttr<"readnone", [ParamAttr]>;
/// Function only reads from memory.
def ReadOnly : EnumAttr<"readonly", [ParamAttr]>;

/// Function is marked to be analyzed by the realtime sanitizer.
def Realtime : EnumAttr<"realtime", [FnAttr]>;
/// Function is marked to be non-blocking
def NonBlocking : EnumAttr<"nonblocking", [FnAttr]>;

/// Return value is always equal to this argument.
def Returned : EnumAttr<"returned", [ParamAttr]>;
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/Bitcode/Reader/BitcodeReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2076,8 +2076,8 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) {
return Attribute::ReadOnly;
case bitc::ATTR_KIND_RETURNED:
return Attribute::Returned;
case bitc::ATTR_KIND_REALTIME:
return Attribute::Realtime;
case bitc::ATTR_KIND_NONBLOCKING:
return Attribute::NonBlocking;
case bitc::ATTR_KIND_NO_SANITIZE_REALTIME:
return Attribute::NoSanitizeRealtime;
case bitc::ATTR_KIND_RETURNS_TWICE:
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -783,8 +783,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
return bitc::ATTR_KIND_OPTIMIZE_FOR_SIZE;
case Attribute::OptimizeNone:
return bitc::ATTR_KIND_OPTIMIZE_NONE;
case Attribute::Realtime:
return bitc::ATTR_KIND_REALTIME;
case Attribute::NonBlocking:
return bitc::ATTR_KIND_NONBLOCKING;
case Attribute::NoSanitizeRealtime:
return bitc::ATTR_KIND_NO_SANITIZE_REALTIME;
case Attribute::ReadNone:
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Transforms/Utils/CodeExtractor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -968,7 +968,7 @@ Function *CodeExtractor::constructFunction(const ValueSet &inputs,
case Attribute::MustProgress:
case Attribute::NoProfile:
case Attribute::SkipProfile:
case Attribute::Realtime:
case Attribute::NonBlocking:
case Attribute::NoSanitizeRealtime:
break;
// These attributes cannot be applied to functions.
Expand Down