[clang] 325c4c2 - [clang] Add test cases for multiversion function overload scenarios in C.

Tom Honermann via cfe-commits cfe-commits at lists.llvm.org
Mon Mar 21 10:39:57 PDT 2022


Author: Tom Honermann
Date: 2022-03-21T13:39:42-04:00
New Revision: 325c4c29d68c3bd25984797414b0e5e11ac505f1

URL: https://github.com/llvm/llvm-project/commit/325c4c29d68c3bd25984797414b0e5e11ac505f1
DIFF: https://github.com/llvm/llvm-project/commit/325c4c29d68c3bd25984797414b0e5e11ac505f1.diff

LOG: [clang] Add test cases for multiversion function overload scenarios in C.

This change adds test cases to validate diagnostics for overloaded sets
that contain declarations of multiversion functions. Many of the added test
cases exercise declarations that are intended to be valid. Others are
intended to be valid if and when restrictions on multiversion functions
being declared with the overloadable attribute are lifted.

Several of the new test cases currently trigger the following assertion
failure in SemaDecl.cpp; the relevant test is therefore marked as an
expected failure pending a fix.
```
Assertion `(Previous.empty() || llvm::any_of(Previous, [](const NamedDecl *ND) { return ND->hasAttr(); })) && "Non-redecls shouldn't happen without overloadable present"' failed.
```

Reviewed By: erichkeane

Differential Revision: https://reviews.llvm.org/D121954

Added: 
    

Modified: 
    clang/test/Sema/attr-cpuspecific.c
    clang/test/Sema/attr-target-clones.c
    clang/test/Sema/attr-target-mv.c

Removed: 
    


################################################################################
diff  --git a/clang/test/Sema/attr-cpuspecific.c b/clang/test/Sema/attr-cpuspecific.c
index 67e4c579bcbcd..572d4d71f0c0e 100644
--- a/clang/test/Sema/attr-cpuspecific.c
+++ b/clang/test/Sema/attr-cpuspecific.c
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -triple x86_64-linux-gnu -Wno-strict-prototypes -fsyntax-only -verify %s -Wnonnull
+// XFAIL: asserts
 
 void __attribute__((cpu_specific(ivybridge))) no_default(void);
 void __attribute__((cpu_specific(sandybridge)))  no_default(void);
@@ -118,3 +119,74 @@ int use3(void) {
 int __attribute__((cpu_dispatch(pentium_iii, pentium_iii_no_xmm_regs))) dupe_p3(void);
 
 void __attribute__((cpu_specific(atom), nothrow, nonnull(1))) addtl_attrs(int*);
+
+// FIXME: Declaration of a non-overloadable function when more than one
+// FIXME: multiversion function declarations are present results in an
+// FIXME: assertion failure.
+int __attribute__((cpu_specific(atom))) bad_overload1(void);
+int __attribute__((cpu_specific(ivybridge))) bad_overload1(void);
+// expected-error at +2 {{at most one overload for a given name may lack the 'overloadable' attribute}}
+// expected-note at -2 {{previous unmarked overload of function is here}}
+int bad_overload1(int);
+
+int bad_overload2(int);
+// expected-error at +2 {{conflicting types for 'bad_overload2'}}
+// expected-note at -2 {{previous declaration is here}}
+int __attribute__((cpu_specific(atom))) bad_overload2(void);
+int __attribute__((cpu_specific(ivybridge))) bad_overload2(void);
+
+// FIXME: Declaration of a non-overloadable function when more than one
+// FIXME: multiversion function declarations are present results in an
+// FIXME: assertion failure.
+int __attribute__((cpu_dispatch(generic))) bad_overload3(void);
+int __attribute__((cpu_specific(ivybridge))) bad_overload3(void);
+// expected-error at +2 {{at most one overload for a given name may lack the 'overloadable' attribute}}
+// expected-note at -2 {{previous unmarked overload of function is here}}
+int bad_overload3(int);
+
+int bad_overload4(int);
+// expected-error at +2 {{conflicting types for 'bad_overload4'}}
+// expected-note at -2 {{previous declaration is here}}
+int __attribute__((cpu_dispatch(generic))) bad_overload4(void);
+int __attribute__((cpu_specific(ivybridge))) bad_overload4(void);
+
+// expected-error at +1 {{attribute 'cpu_specific' multiversioning cannot be combined with attribute 'overloadable'}}
+int __attribute__((__overloadable__)) __attribute__((cpu_specific(generic))) bad_overload5(void);
+int __attribute__((cpu_specific(ivybridge))) bad_overload5(void);
+
+int __attribute__((cpu_specific(generic))) bad_overload6(void);
+// expected-error at +1 {{attribute 'cpu_specific' multiversioning cannot be combined with attribute 'overloadable'}}
+int __attribute__((__overloadable__)) __attribute__((cpu_specific(ivybridge))) bad_overload6(void);
+
+int __attribute__((cpu_specific(atom))) good_overload1(void);
+int __attribute__((cpu_specific(ivybridge))) good_overload1(void);
+int __attribute__((__overloadable__)) good_overload1(int);
+
+int __attribute__((__overloadable__)) good_overload2(int);
+int __attribute__((cpu_specific(atom))) good_overload2(void);
+int __attribute__((cpu_specific(ivybridge))) good_overload2(void);
+
+// expected-error at +1 {{attribute 'cpu_specific' multiversioning cannot be combined with attribute 'overloadable'}}
+int __attribute__((__overloadable__)) __attribute__((cpu_specific(atom))) good_overload3(void);
+// expected-error at +1 {{attribute 'cpu_specific' multiversioning cannot be combined with attribute 'overloadable'}}
+int __attribute__((__overloadable__)) __attribute__((cpu_specific(ivybridge))) good_overload3(void);
+int good_overload3(int);
+
+int good_overload4(int);
+// expected-error at +1 {{attribute 'cpu_specific' multiversioning cannot be combined with attribute 'overloadable'}}
+int __attribute__((__overloadable__)) __attribute__((cpu_specific(atom))) good_overload4(void);
+// expected-error at +1 {{attribute 'cpu_specific' multiversioning cannot be combined with attribute 'overloadable'}}
+int __attribute__((__overloadable__)) __attribute__((cpu_specific(ivybridge))) good_overload4(void);
+
+// expected-error at +1 {{attribute 'cpu_specific' multiversioning cannot be combined with attribute 'overloadable'}}
+int __attribute__((__overloadable__)) __attribute__((cpu_specific(atom))) good_overload5(void);
+// expected-error at +1 {{attribute 'cpu_specific' multiversioning cannot be combined with attribute 'overloadable'}}
+int __attribute__((__overloadable__)) __attribute__((cpu_specific(ivybridge))) good_overload5(int);
+
+int __attribute__((cpu_specific(atom))) good_overload6(void);
+// expected-error at +1 {{attribute 'cpu_specific' multiversioning cannot be combined with attribute 'overloadable'}}
+int __attribute__((__overloadable__)) __attribute__((cpu_specific(ivybridge))) good_overload6(int);
+
+// expected-error at +1 {{attribute 'cpu_specific' multiversioning cannot be combined with attribute 'overloadable'}}
+int __attribute__((__overloadable__)) __attribute__((cpu_specific(atom))) good_overload7(void);
+int __attribute__((cpu_specific(ivybridge))) good_overload7(int);

diff  --git a/clang/test/Sema/attr-target-clones.c b/clang/test/Sema/attr-target-clones.c
index 46da36d2e1e7b..d4443e12db4ce 100644
--- a/clang/test/Sema/attr-target-clones.c
+++ b/clang/test/Sema/attr-target-clones.c
@@ -86,3 +86,31 @@ int useage(void) {
 // expected-error at +1 {{function declaration cannot become a multiversioned function after first usage}}
 int __attribute__((target_clones("sse4.2", "default"))) mv_after_use(void) { return 1; }
 
+void bad_overload1(void) __attribute__((target_clones("mmx", "sse4.2", "default")));
+void bad_overload1(int p) {}
+
+void bad_overload2(int p) {}
+void bad_overload2(void) __attribute__((target_clones("mmx", "sse4.2", "default")));
+
+void bad_overload3(void) __attribute__((target_clones("mmx", "sse4.2", "default")));
+void bad_overload3(int) __attribute__((target_clones("mmx", "sse4.2", "default")));
+
+void good_overload1(void) __attribute__((target_clones("mmx", "sse4.2", "default")));
+void __attribute__((__overloadable__)) good_overload1(int p) {}
+
+// expected-error at +1 {{attribute 'target_clones' multiversioning cannot be combined with attribute 'overloadable'}}
+void __attribute__((__overloadable__)) good_overload2(void) __attribute__((target_clones("mmx", "sse4.2", "default")));
+void good_overload2(int p) {}
+
+// expected-error at +1 {{attribute 'target_clones' multiversioning cannot be combined with attribute 'overloadable'}}
+void __attribute__((__overloadable__)) good_overload3(void) __attribute__((target_clones("mmx", "sse4.2", "default")));
+// expected-error at +1 {{attribute 'target_clones' multiversioning cannot be combined with attribute 'overloadable'}}
+void __attribute__((__overloadable__)) good_overload3(int) __attribute__((target_clones("mmx", "sse4.2", "default")));
+
+void good_overload4(void) __attribute__((target_clones("mmx", "sse4.2", "default")));
+// expected-error at +1 {{attribute 'target_clones' multiversioning cannot be combined with attribute 'overloadable'}}
+void __attribute__((__overloadable__)) good_overload4(int) __attribute__((target_clones("mmx", "sse4.2", "default")));
+
+// expected-error at +1 {{attribute 'target_clones' multiversioning cannot be combined with attribute 'overloadable'}}
+void __attribute__((__overloadable__)) good_overload5(void) __attribute__((target_clones("mmx", "sse4.2", "default")));
+void good_overload5(int) __attribute__((target_clones("mmx", "sse4.2", "default")));

diff  --git a/clang/test/Sema/attr-target-mv.c b/clang/test/Sema/attr-target-mv.c
index 174a3c8773e66..e5792ba01d07b 100644
--- a/clang/test/Sema/attr-target-mv.c
+++ b/clang/test/Sema/attr-target-mv.c
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -triple x86_64-linux-gnu -Wno-strict-prototypes -fsyntax-only -verify %s
+// XFAIL: asserts
 
 void __attribute__((target("sse4.2"))) no_default(void);
 void __attribute__((target("arch=sandybridge")))  no_default(void);
@@ -108,3 +109,60 @@ void __attribute__((target("arch=sandybridge"))) addtl_attrs5(int*);
 void __attribute__((target("sse4.2"))) addtl_attrs6(int*);
 void __attribute__((target("arch=sandybridge"), nothrow, used, nonnull)) addtl_attrs6(int*);
 
+// FIXME: Declaration of a non-overloadable function when more than one
+// FIXME: multiversion function declarations are present results in an
+// FIXME: assertion failure.
+int __attribute__((target("sse4.2"))) bad_overload1(void);
+int __attribute__((target("arch=sandybridge"))) bad_overload1(void);
+// expected-error at +2 {{at most one overload for a given name may lack the 'overloadable' attribute}}
+// expected-note at -2 {{previous unmarked overload of function is here}}
+int bad_overload1(int);
+
+int bad_overload2(int);
+// expected-error at +2 {{conflicting types for 'bad_overload2'}}
+// expected-note at -2 {{previous declaration is here}}
+int __attribute__((target("sse4.2"))) bad_overload2(void);
+// expected-error at +2 {{conflicting types for 'bad_overload2'}}
+// expected-note at -5 {{previous declaration is here}}
+int __attribute__((target("arch=sandybridge"))) bad_overload2(void);
+
+// expected-error at +2 {{attribute 'target' multiversioning cannot be combined with attribute 'overloadable'}}
+// expected-note at +2 {{function multiversioning caused by this declaration}}
+int __attribute__((__overloadable__)) __attribute__((target("sse4.2"))) bad_overload3(void);
+int __attribute__((target("arch=sandybridge"))) bad_overload3(void);
+
+int __attribute__((target("sse4.2"))) bad_overload4(void);
+// expected-error at +1 {{attribute 'target' multiversioning cannot be combined with attribute 'overloadable'}}
+int __attribute__((__overloadable__)) __attribute__((target("arch=sandybridge"))) bad_overload4(void);
+
+int __attribute__((target("sse4.2"))) bad_overload5(void);
+int __attribute__((target("arch=sandybridge"))) bad_overload5(int);
+
+int __attribute__((target("sse4.2"))) good_overload1(void);
+int __attribute__((target("arch=sandybridge"))) good_overload1(void);
+int __attribute__((__overloadable__)) good_overload1(int);
+
+int __attribute__((__overloadable__)) good_overload2(int);
+int __attribute__((target("sse4.2"))) good_overload2(void);
+int __attribute__((target("arch=sandybridge"))) good_overload2(void);
+
+// expected-error at +2 {{attribute 'target' multiversioning cannot be combined with attribute 'overloadable'}}
+// expected-note at +2 {{function multiversioning caused by this declaration}}
+int __attribute__((__overloadable__)) __attribute__((target("sse4.2"))) good_overload3(void);
+int __attribute__((__overloadable__)) __attribute__((target("arch=sandybridge"))) good_overload3(void);
+int good_overload3(int);
+
+int good_overload4(int);
+// expected-error at +2 {{attribute 'target' multiversioning cannot be combined with attribute 'overloadable'}}
+// expected-note at +2 {{function multiversioning caused by this declaration}}
+int __attribute__((__overloadable__)) __attribute__((target("sse4.2"))) good_overload4(void);
+int __attribute__((__overloadable__)) __attribute__((target("arch=sandybridge"))) good_overload4(void);
+
+int __attribute__((__overloadable__)) __attribute__((target("sse4.2"))) good_overload5(void);
+int __attribute__((__overloadable__)) __attribute__((target("arch=sandybridge"))) good_overload5(int);
+
+int __attribute__((target("sse4.2"))) good_overload6(void);
+int __attribute__((__overloadable__)) __attribute__((target("arch=sandybridge"))) good_overload6(int);
+
+int __attribute__((__overloadable__)) __attribute__((target("sse4.2"))) good_overload7(void);
+int __attribute__((target("arch=sandybridge"))) good_overload7(int);


        


More information about the cfe-commits mailing list