@@ -1832,6 +1832,42 @@ void CodeGenModule::AddDefaultFnAttrs(llvm::Function &F) {
1832
1832
F.addAttributes (llvm::AttributeList::FunctionIndex, FuncAttrs);
1833
1833
}
1834
1834
1835
+ static void addNoBuiltinAttributes (llvm::AttrBuilder &FuncAttrs,
1836
+ const LangOptions &LangOpts,
1837
+ const NoBuiltinAttr *NBA = nullptr ) {
1838
+ auto AddNoBuiltinAttr = [&FuncAttrs](StringRef BuiltinName) {
1839
+ SmallString<32 > AttributeName;
1840
+ AttributeName += " no-builtin-" ;
1841
+ AttributeName += BuiltinName;
1842
+ FuncAttrs.addAttribute (AttributeName);
1843
+ };
1844
+
1845
+ // First, handle the language options passed through -fno-builtin[-<name>]
1846
+ if (LangOpts.NoBuiltin ) {
1847
+ // -fno-builtin disables them all.
1848
+ FuncAttrs.addAttribute (" no-builtins" );
1849
+ return ;
1850
+ }
1851
+
1852
+ // Then, add attributes for builtins specified through -fno-builtin-<name>.
1853
+ llvm::for_each (LangOpts.NoBuiltinFuncs , AddNoBuiltinAttr);
1854
+
1855
+ // Now, let's check the __attribute__((no_builtin("...")) attribute added to
1856
+ // the source.
1857
+ if (!NBA)
1858
+ return ;
1859
+
1860
+ // If there is a wildcard in the builtin names specified through the
1861
+ // attribute, disable them all.
1862
+ if (llvm::is_contained (NBA->builtinNames (), " *" )) {
1863
+ FuncAttrs.addAttribute (" no-builtins" );
1864
+ return ;
1865
+ }
1866
+
1867
+ // And last, add the rest of the builtin names.
1868
+ llvm::for_each (NBA->builtinNames (), AddNoBuiltinAttr);
1869
+ }
1870
+
1835
1871
void CodeGenModule::ConstructAttributeList (
1836
1872
StringRef Name, const CGFunctionInfo &FI, CGCalleeInfo CalleeInfo,
1837
1873
llvm::AttributeList &AttrList, unsigned &CallingConv, bool AttrOnCallSite) {
@@ -1850,6 +1886,8 @@ void CodeGenModule::ConstructAttributeList(
1850
1886
const Decl *TargetDecl = CalleeInfo.getCalleeDecl ().getDecl ();
1851
1887
1852
1888
bool HasOptnone = false ;
1889
+ // The NoBuiltinAttr attached to a TargetDecl (only allowed on FunctionDecls).
1890
+ const NoBuiltinAttr *NBA = nullptr ;
1853
1891
// FIXME: handle sseregparm someday...
1854
1892
if (TargetDecl) {
1855
1893
if (TargetDecl->hasAttr <ReturnsTwiceAttr>())
@@ -1875,22 +1913,7 @@ void CodeGenModule::ConstructAttributeList(
1875
1913
if (!(AttrOnCallSite && IsVirtualCall)) {
1876
1914
if (Fn->isNoReturn ())
1877
1915
FuncAttrs.addAttribute (llvm::Attribute::NoReturn);
1878
-
1879
- const auto *NBA = Fn->getAttr <NoBuiltinAttr>();
1880
- bool HasWildcard = NBA && llvm::is_contained (NBA->builtinNames (), " *" );
1881
- if (getLangOpts ().NoBuiltin || HasWildcard)
1882
- FuncAttrs.addAttribute (" no-builtins" );
1883
- else {
1884
- auto AddNoBuiltinAttr = [&FuncAttrs](StringRef BuiltinName) {
1885
- SmallString<32 > AttributeName;
1886
- AttributeName += " no-builtin-" ;
1887
- AttributeName += BuiltinName;
1888
- FuncAttrs.addAttribute (AttributeName);
1889
- };
1890
- llvm::for_each (getLangOpts ().NoBuiltinFuncs , AddNoBuiltinAttr);
1891
- if (NBA)
1892
- llvm::for_each (NBA->builtinNames (), AddNoBuiltinAttr);
1893
- }
1916
+ NBA = Fn->getAttr <NoBuiltinAttr>();
1894
1917
}
1895
1918
}
1896
1919
@@ -1925,6 +1948,14 @@ void CodeGenModule::ConstructAttributeList(
1925
1948
}
1926
1949
}
1927
1950
1951
+ // Attach "no-builtins" attributes to:
1952
+ // * call sites: both `nobuiltin` and "no-builtins" or "no-builtin-<name>".
1953
+ // * definitions: "no-builtins" or "no-builtin-<name>" only.
1954
+ // The attributes can come from:
1955
+ // * LangOpts: -ffreestanding, -fno-builtin, -fno-builtin-<name>
1956
+ // * FunctionDecl attributes: __attribute__((no_builtin(...)))
1957
+ addNoBuiltinAttributes (FuncAttrs, getLangOpts (), NBA);
1958
+
1928
1959
ConstructDefaultFnAttrList (Name, HasOptnone, AttrOnCallSite, FuncAttrs);
1929
1960
1930
1961
// This must run after constructing the default function attribute list
0 commit comments