blob: 82b902a7f593ee2d793caca5c50429931b92577c [file] [log] [blame]
Nick Lewycky36e9b3c2014-01-21 04:31:12 +00001// RUN: %clang_cc1 %s -verify
2// RUN: %clang_cc1 %s -DCODEGEN -emit-llvm -o - | FileCheck %s
Nick Lewycky35a6ef42014-01-11 02:50:57 +00003
4#define O_CREAT 0x100
5typedef int mode_t;
6typedef unsigned long size_t;
7
8int open(const char *pathname, int flags) __attribute__((enable_if(!(flags & O_CREAT), "must specify mode when using O_CREAT"))) __attribute__((overloadable)); // expected-note{{candidate disabled: must specify mode when using O_CREAT}}
9int open(const char *pathname, int flags, mode_t mode) __attribute__((overloadable)); // expected-note{{candidate function not viable: requires 3 arguments, but 2 were provided}}
10
11void test1() {
12#ifndef CODEGEN
13 open("path", O_CREAT); // expected-error{{no matching function for call to 'open'}}
14#endif
15 open("path", O_CREAT, 0660);
16 open("path", 0);
17 open("path", 0, 0);
18}
19
20size_t __strnlen_chk(const char *s, size_t requested_amount, size_t s_len);
21
22size_t strnlen(const char *s, size_t maxlen) // expected-note{{candidate function}}
23 __attribute__((overloadable))
24 __asm__("strnlen_real1");
25
26__attribute__((always_inline))
27inline size_t strnlen(const char *s, size_t maxlen) // expected-note{{candidate function}}
28 __attribute__((overloadable))
29 __attribute__((enable_if(__builtin_object_size(s, 0) != -1,
30 "chosen when target buffer size is known")))
31{
32 return __strnlen_chk(s, maxlen, __builtin_object_size(s, 0));
33}
34
35size_t strnlen(const char *s, size_t maxlen) // expected-note{{candidate disabled: chosen when 'maxlen' is known to be less than or equal to the buffer size}}
36 __attribute__((overloadable))
37 __attribute__((enable_if(__builtin_object_size(s, 0) != -1,
38 "chosen when target buffer size is known")))
39 __attribute__((enable_if(maxlen <= __builtin_object_size(s, 0),
40 "chosen when 'maxlen' is known to be less than or equal to the buffer size")))
41 __asm__("strnlen_real2");
42
43size_t strnlen(const char *s, size_t maxlen) // expected-note{{candidate function has been explicitly made unavailable}}
44 __attribute__((overloadable))
45 __attribute__((enable_if(__builtin_object_size(s, 0) != -1,
46 "chosen when target buffer size is known")))
47 __attribute__((enable_if(maxlen > __builtin_object_size(s, 0),
48 "chosen when 'maxlen' is larger than the buffer size")))
49 __attribute__((unavailable("'maxlen' is larger than the buffer size")));
50
51void test2(const char *s, int i) {
David Blaikieea3e51d2015-06-29 17:29:50 +000052// CHECK: define {{.*}}void @test2
Nick Lewycky35a6ef42014-01-11 02:50:57 +000053 const char c[123];
54 strnlen(s, i);
55// CHECK: call {{.*}}strnlen_real1
56 strnlen(s, 999);
57// CHECK: call {{.*}}strnlen_real1
58 strnlen(c, 1);
59// CHECK: call {{.*}}strnlen_real2
60 strnlen(c, i);
61// CHECK: call {{.*}}strnlen_chk
62#ifndef CODEGEN
63 strnlen(c, 999); // expected-error{{call to unavailable function 'strnlen': 'maxlen' is larger than the buffer size}}
64#endif
65}
66
67int isdigit(int c) __attribute__((overloadable)); // expected-note{{candidate function}}
68int isdigit(int c) __attribute__((overloadable)) // expected-note{{candidate function has been explicitly made unavailable}}
69 __attribute__((enable_if(c <= -1 || c > 255, "'c' must have the value of an unsigned char or EOF")))
70 __attribute__((unavailable("'c' must have the value of an unsigned char or EOF")));
71
72void test3(int c) {
73 isdigit(c);
74 isdigit(10);
75#ifndef CODEGEN
76 isdigit(-10); // expected-error{{call to unavailable function 'isdigit': 'c' must have the value of an unsigned char or EOF}}
77#endif
78}
79
Ulrich Weigandef5aa292015-07-13 14:13:01 +000080// Verify that the alternate spelling __enable_if__ works as well.
81int isdigit2(int c) __attribute__((overloadable)); // expected-note{{candidate function}}
82int isdigit2(int c) __attribute__((overloadable)) // expected-note{{candidate function has been explicitly made unavailable}}
83 __attribute__((__enable_if__(c <= -1 || c > 255, "'c' must have the value of an unsigned char or EOF")))
84 __attribute__((unavailable("'c' must have the value of an unsigned char or EOF")));
85
86void test4(int c) {
87 isdigit2(c);
88 isdigit2(10);
89#ifndef CODEGEN
90 isdigit2(-10); // expected-error{{call to unavailable function 'isdigit2': 'c' must have the value of an unsigned char or EOF}}
91#endif
92}
93
George Burgess IV5f21c712015-10-12 19:57:04 +000094void test5() {
95 int (*p1)(int) = &isdigit2;
96 int (*p2)(int) = isdigit2;
97 void *p3 = (void *)&isdigit2;
98 void *p4 = (void *)isdigit2;
99}
Ulrich Weigandef5aa292015-07-13 14:13:01 +0000100
Nick Lewycky35a6ef42014-01-11 02:50:57 +0000101#ifndef CODEGEN
102__attribute__((enable_if(n == 0, "chosen when 'n' is zero"))) void f1(int n); // expected-error{{use of undeclared identifier 'n'}}
103
104int n __attribute__((enable_if(1, "always chosen"))); // expected-warning{{'enable_if' attribute only applies to functions}}
105
106void f(int n) __attribute__((enable_if("chosen when 'n' is zero", n == 0))); // expected-error{{'enable_if' attribute requires a string}}
107
108void f(int n) __attribute__((enable_if())); // expected-error{{'enable_if' attribute requires exactly 2 arguments}}
109
110void f(int n) __attribute__((enable_if(unresolvedid, "chosen when 'unresolvedid' is non-zero"))); // expected-error{{use of undeclared identifier 'unresolvedid'}}
111
112int global;
113void f(int n) __attribute__((enable_if(global == 0, "chosen when 'global' is zero"))); // expected-error{{'enable_if' attribute expression never produces a constant expression}} // expected-note{{subexpression not valid in a constant expression}}
114
115const int cst = 7;
116void return_cst(void) __attribute__((overloadable)) __attribute__((enable_if(cst == 7, "chosen when 'cst' is 7")));
117void test_return_cst() { return_cst(); }
George Burgess IV5f21c712015-10-12 19:57:04 +0000118
119void f2(void) __attribute__((overloadable)) __attribute__((enable_if(1, "always chosen")));
120void f2(void) __attribute__((overloadable)) __attribute__((enable_if(0, "never chosen")));
121void f2(void) __attribute__((overloadable));
122void test6() {
123 void (*p1)(void) = &f2; // expected-error{{initializing 'void (*)(void)' with an expression of incompatible type '<overloaded function type>'}} expected-note@119{{candidate function}} expected-note@120{{candidate function made ineligible by enable_if}} expected-note@121{{candidate function}}
124 void (*p2)(void) = f2; // expected-error{{initializing 'void (*)(void)' with an expression of incompatible type '<overloaded function type>'}} expected-note@119{{candidate function}} expected-note@120{{candidate function made ineligible by enable_if}} expected-note@121{{candidate function}}
125 void *p3 = (void*)&f2; // expected-error{{address of overloaded function 'f2' is ambiguous}} expected-note@119{{candidate function}} expected-note@120{{candidate function made ineligible by enable_if}} expected-note@121{{candidate function}}
126 void *p4 = (void*)f2; // expected-error{{address of overloaded function 'f2' is ambiguous}} expected-note@119{{candidate function}} expected-note@120{{candidate function made ineligible by enable_if}} expected-note@121{{candidate function}}
127}
128
129void f3(int m) __attribute__((overloadable)) __attribute__((enable_if(m >= 0, "positive")));
130void f3(int m) __attribute__((overloadable)) __attribute__((enable_if(m < 0, "negative")));
131void test7() {
132 void (*p1)(int) = &f3; // expected-error{{initializing 'void (*)(int)' with an expression of incompatible type '<overloaded function type>'}} expected-note@129{{candidate function made ineligible by enable_if}} expected-note@130{{candidate function made ineligible by enable_if}}
133 void (*p2)(int) = f3; // expected-error{{initializing 'void (*)(int)' with an expression of incompatible type '<overloaded function type>'}} expected-note@129{{candidate function made ineligible by enable_if}} expected-note@130{{candidate function made ineligible by enable_if}}
134 void *p3 = (void*)&f3; // expected-error{{address of overloaded function 'f3' does not match required type 'void'}} expected-note@129{{candidate function made ineligible by enable_if}} expected-note@130{{candidate function made ineligible by enable_if}}
135 void *p4 = (void*)f3; // expected-error{{address of overloaded function 'f3' does not match required type 'void'}} expected-note@129{{candidate function made ineligible by enable_if}} expected-note@130{{candidate function made ineligible by enable_if}}
136}
Nick Lewycky35a6ef42014-01-11 02:50:57 +0000137#endif