emaste created this revision. emaste added a reviewer: DmitryPolukhin. Herald added a reviewer: javed.absar. Herald added subscribers: kristof.beyls, krytarowski.
When ifunc support was added to Clang (in https://reviews.llvm.org/rC265917) it did not allow resolvers to take function arguments. This was based on GCC's documentation, which states resolvers return a pointer and take no arguments. However, GCC actually allows it, and glibc (on non-x86 platforms) and FreeBSD (on x86 and arm64) pass CPU identification information as arguments to ifunc resolvers. I believe GCC's documentation is simply incorrect / out-of-date. We've removed the prohibition in FreeBSD's in-tree Clang: https://svnweb.freebsd.org/changeset/base/339019. https://reviews.llvm.org/D52703 Files: include/clang/Basic/AttrDocs.td include/clang/Basic/DiagnosticSemaKinds.td lib/CodeGen/CodeGenModule.cpp test/Sema/attr-ifunc.c Index: test/Sema/attr-ifunc.c =================================================================== --- test/Sema/attr-ifunc.c +++ test/Sema/attr-ifunc.c @@ -27,10 +27,6 @@ void f4() __attribute__((ifunc("f4_ifunc"))); //expected-error@-1 {{ifunc resolver function must return a pointer}} -void* f5_ifunc(int i) { return 0; } -void f5() __attribute__((ifunc("f5_ifunc"))); -//expected-error@-1 {{ifunc resolver function must have no parameters}} - #else void f1a() __asm("f1"); void f1a() {} Index: lib/CodeGen/CodeGenModule.cpp =================================================================== --- lib/CodeGen/CodeGenModule.cpp +++ lib/CodeGen/CodeGenModule.cpp @@ -322,8 +322,6 @@ assert(FTy); if (!FTy->getReturnType()->isPointerTy()) Diags.Report(Location, diag::err_ifunc_resolver_return); - if (FTy->getNumParams()) - Diags.Report(Location, diag::err_ifunc_resolver_params); } llvm::Constant *Aliasee = Alias->getIndirectSymbol(); Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -2887,8 +2887,6 @@ "%select{alias|ifunc}0 definition is part of a cycle">; def err_ifunc_resolver_return : Error< "ifunc resolver function must return a pointer">; -def err_ifunc_resolver_params : Error< - "ifunc resolver function must have no parameters">; def warn_attribute_wrong_decl_type_str : Warning< "%0 attribute only applies to %1">, InGroup<IgnoredAttributes>; def err_attribute_wrong_decl_type_str : Error< Index: include/clang/Basic/AttrDocs.td =================================================================== --- include/clang/Basic/AttrDocs.td +++ include/clang/Basic/AttrDocs.td @@ -3366,7 +3366,7 @@ let Content = [{ ``__attribute__((ifunc("resolver")))`` is used to mark that the address of a declaration should be resolved at runtime by calling a resolver function. -The symbol name of the resolver function is given in quotes. A function with this name (after mangling) must be defined in the current translation unit; it may be ``static``. The resolver function should take no arguments and return a pointer. +The symbol name of the resolver function is given in quotes. A function with this name (after mangling) must be defined in the current translation unit; it may be ``static``. The resolver function should return a pointer. The ``ifunc`` attribute may only be used on a function declaration. A function declaration with an ``ifunc`` attribute is considered to be a definition of the declared entity. The entity must not have weak linkage; for example, in C++, it cannot be applied to a declaration if a definition at that location would be considered inline.
Index: test/Sema/attr-ifunc.c =================================================================== --- test/Sema/attr-ifunc.c +++ test/Sema/attr-ifunc.c @@ -27,10 +27,6 @@ void f4() __attribute__((ifunc("f4_ifunc"))); //expected-error@-1 {{ifunc resolver function must return a pointer}} -void* f5_ifunc(int i) { return 0; } -void f5() __attribute__((ifunc("f5_ifunc"))); -//expected-error@-1 {{ifunc resolver function must have no parameters}} - #else void f1a() __asm("f1"); void f1a() {} Index: lib/CodeGen/CodeGenModule.cpp =================================================================== --- lib/CodeGen/CodeGenModule.cpp +++ lib/CodeGen/CodeGenModule.cpp @@ -322,8 +322,6 @@ assert(FTy); if (!FTy->getReturnType()->isPointerTy()) Diags.Report(Location, diag::err_ifunc_resolver_return); - if (FTy->getNumParams()) - Diags.Report(Location, diag::err_ifunc_resolver_params); } llvm::Constant *Aliasee = Alias->getIndirectSymbol(); Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -2887,8 +2887,6 @@ "%select{alias|ifunc}0 definition is part of a cycle">; def err_ifunc_resolver_return : Error< "ifunc resolver function must return a pointer">; -def err_ifunc_resolver_params : Error< - "ifunc resolver function must have no parameters">; def warn_attribute_wrong_decl_type_str : Warning< "%0 attribute only applies to %1">, InGroup<IgnoredAttributes>; def err_attribute_wrong_decl_type_str : Error< Index: include/clang/Basic/AttrDocs.td =================================================================== --- include/clang/Basic/AttrDocs.td +++ include/clang/Basic/AttrDocs.td @@ -3366,7 +3366,7 @@ let Content = [{ ``__attribute__((ifunc("resolver")))`` is used to mark that the address of a declaration should be resolved at runtime by calling a resolver function. -The symbol name of the resolver function is given in quotes. A function with this name (after mangling) must be defined in the current translation unit; it may be ``static``. The resolver function should take no arguments and return a pointer. +The symbol name of the resolver function is given in quotes. A function with this name (after mangling) must be defined in the current translation unit; it may be ``static``. The resolver function should return a pointer. The ``ifunc`` attribute may only be used on a function declaration. A function declaration with an ``ifunc`` attribute is considered to be a definition of the declared entity. The entity must not have weak linkage; for example, in C++, it cannot be applied to a declaration if a definition at that location would be considered inline.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits