-
Notifications
You must be signed in to change notification settings - Fork 14.5k
[clang] "modular_format" attribute for functions using format strings #147431
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: users/mysterymath/modular-printf/ir
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -9427,3 +9427,37 @@ diagnostics with code like: | |||||
__attribute__((nonstring)) char NotAStr[3] = "foo"; // Not diagnosed | ||||||
}]; | ||||||
} | ||||||
|
||||||
def ModularFormatDocs : Documentation { | ||||||
let Category = DocCatFunction; | ||||||
let Content = [{ | ||||||
The ``modular_format`` attribute can be applied to a function that bears the | ||||||
``format`` attribute (or standard library functions) to indicate that the | ||||||
implementation is modular on the format string argument. When the format string | ||||||
for a given call is constant, the compiler may redirect the call to the symbol | ||||||
given as the first argument to the attribute (the modular implementation | ||||||
function). | ||||||
|
||||||
The second argument is a implementation name, and the remaining arguments are | ||||||
aspects of the format string for the compiler to report. If the compiler does | ||||||
not understand a aspect, it must summarily report that the format string has | ||||||
that aspect. | ||||||
|
||||||
The compiler reports an aspect by issing a relocation for the symbol | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
``<impl_name>_<aspect>``. This arranges for code and data needed to support the | ||||||
aspect of the implementation to be brought into the link to satisfy weak | ||||||
references in the modular implemenation function. | ||||||
|
||||||
For example, say ``printf`` is annotated with | ||||||
``modular_format(__modular_printf, __printf, float)``. Then, a call to | ||||||
``printf(var, 42)`` would be untouched. A call to ``printf("%d", 42)`` would | ||||||
become a call to ``__modular_printf`` with the same arguments, as would | ||||||
``printf("%f", 42.0)``. The latter would be accompanied with a strong | ||||||
relocation against the symbol ``__printf_float``, which would bring floating | ||||||
point support for ``printf`` into the link. | ||||||
|
||||||
The following aspects are currently supported: | ||||||
|
||||||
- ``float``: The call has a floating point argument | ||||||
}]; | ||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2569,6 +2569,18 @@ void CodeGenModule::ConstructAttributeList(StringRef Name, | |
|
||
if (TargetDecl->hasAttr<ArmLocallyStreamingAttr>()) | ||
FuncAttrs.addAttribute("aarch64_pstate_sm_body"); | ||
|
||
if (auto *ModularFormat = TargetDecl->getAttr<ModularFormatAttr>()) { | ||
// TODO: Error checking | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a heck of a TODO :) Though, I'd expect us to do diagnostics during our normal checking of the format string, so we shouldn't really require anything here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hah, fair; this is very much a Draft PR. My intent was to get this in front of a bunch of eyes sooner rather than later, as this PR set touches everything every layer from the compiler through to libc (skipping the linker). |
||
FormatAttr *Format = TargetDecl->getAttr<FormatAttr>(); | ||
std::string FormatIdx = std::to_string(Format->getFormatIdx()); | ||
std::string FirstArg = std::to_string(Format->getFirstArg()); | ||
SmallVector<StringRef> Args = { | ||
FormatIdx, FirstArg, ModularFormat->getModularImplFn()->getName(), | ||
ModularFormat->getImplName()}; | ||
llvm::append_range(Args, ModularFormat->aspects()); | ||
FuncAttrs.addAttribute("modular-format", llvm::join(Args, ",")); | ||
} | ||
} | ||
|
||
// Attach "no-builtins" attributes to: | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.