2017-01-09 12:12:14 +08:00
// RUN: %clang_cc1 %s -verify -fno-builtin
# define _diagnose_if(...) __attribute__((diagnose_if(__VA_ARGS__)))
void failure ( ) _diagnose_if ( ) ; // expected-error{{exactly 3 arguments}}
void failure ( ) _diagnose_if ( 0 ) ; // expected-error{{exactly 3 arguments}}
void failure ( ) _diagnose_if ( 0 , " " ) ; // expected-error{{exactly 3 arguments}}
void failure ( ) _diagnose_if ( 0 , " " , " error " , 1 ) ; // expected-error{{exactly 3 arguments}}
void failure ( ) _diagnose_if ( 0 , 0 , " error " ) ; // expected-error{{requires a string}}
void failure ( ) _diagnose_if ( 0 , " " , " invalid " ) ; // expected-error{{invalid diagnostic type for 'diagnose_if'; use "error" or "warning" instead}}
void failure ( ) _diagnose_if ( 0 , " " , " ERROR " ) ; // expected-error{{invalid diagnostic type}}
void failure ( int a ) _diagnose_if ( a , " " , " " ) ; // expected-error{{invalid diagnostic type}}
void failure ( ) _diagnose_if ( a , " " , " " ) ; // expected-error{{undeclared identifier 'a'}}
int globalVar ;
void never_constant ( ) _diagnose_if ( globalVar , " " , " error " ) ; // expected-error{{'diagnose_if' attribute expression never produces a constant expression}} expected-note{{subexpression not valid}}
void never_constant ( ) _diagnose_if ( globalVar , " " , " warning " ) ; // expected-error{{'diagnose_if' attribute expression never produces a constant expression}} expected-note{{subexpression not valid}}
int alwaysok ( int q ) _diagnose_if ( 0 , " " , " error " ) ;
int neverok ( int q ) _diagnose_if ( 1 , " oh no " , " error " ) ; // expected-note 5{{from 'diagnose_if' attribute on 'neverok'}}
int alwayswarn ( int q ) _diagnose_if ( 1 , " oh no " , " warning " ) ; // expected-note 5{{from 'diagnose_if' attribute}}
int neverwarn ( int q ) _diagnose_if ( 0 , " " , " warning " ) ;
void runConstant ( ) {
int m ;
alwaysok ( 0 ) ;
alwaysok ( 1 ) ;
alwaysok ( m ) ;
{
int ( * pok ) ( int ) = alwaysok ;
pok = & alwaysok ;
}
neverok ( 0 ) ; // expected-error{{oh no}}
neverok ( 1 ) ; // expected-error{{oh no}}
neverok ( m ) ; // expected-error{{oh no}}
{
int ( * pok ) ( int ) = neverok ; // expected-error{{oh no}}
pok = & neverok ; // expected-error{{oh no}}
}
alwayswarn ( 0 ) ; // expected-warning{{oh no}}
alwayswarn ( 1 ) ; // expected-warning{{oh no}}
alwayswarn ( m ) ; // expected-warning{{oh no}}
{
int ( * pok ) ( int ) = alwayswarn ; // expected-warning{{oh no}}
pok = & alwayswarn ; // expected-warning{{oh no}}
}
neverwarn ( 0 ) ;
neverwarn ( 1 ) ;
neverwarn ( m ) ;
{
int ( * pok ) ( int ) = neverwarn ;
pok = & neverwarn ;
}
}
int abs ( int q ) _diagnose_if ( q > = 0 , " redundant abs call " , " error " ) ; //expected-note{{from 'diagnose_if'}}
void runVariable ( ) {
int m ;
abs ( - 1 ) ;
abs ( 1 ) ; // expected-error{{redundant abs call}}
abs ( m ) ;
int ( * pabs ) ( int ) = abs ;
pabs = & abs ;
}
# define _overloadable __attribute__((overloadable))
2017-01-28 10:19:40 +08:00
int ovl1 ( const char * n ) _overloadable _diagnose_if ( n , " oh no " , " error " ) ; // expected-note{{from 'diagnose_if'}}
int ovl1 ( void * m ) _overloadable ;
2017-01-09 12:12:14 +08:00
int ovl2 ( const char * n ) _overloadable _diagnose_if ( n , " oh no " , " error " ) ; // expected-note{{candidate function}}
int ovl2 ( char * m ) _overloadable ; // expected-note{{candidate function}}
void overloadsYay ( ) {
ovl1 ( ( void * ) 0 ) ;
2017-01-28 10:19:40 +08:00
ovl1 ( " " ) ; // expected-error{{oh no}}
2017-01-09 12:12:14 +08:00
ovl2 ( ( void * ) 0 ) ; // expected-error{{ambiguous}}
}
void errorWarnDiagnose1 ( ) _diagnose_if ( 1 , " oh no " , " error " ) / / expected - note { { from ' diagnose_if ' } }
_diagnose_if ( 1 , " nop " , " warning " ) ;
void errorWarnDiagnose2 ( ) _diagnose_if ( 1 , " oh no " , " error " ) / / expected - note { { from ' diagnose_if ' } }
_diagnose_if ( 1 , " nop " , " error " ) ;
void errorWarnDiagnose3 ( ) _diagnose_if ( 1 , " nop " , " warning " )
_diagnose_if ( 1 , " oh no " , " error " ) ; // expected-note{{from 'diagnose_if'}}
void errorWarnDiagnoseArg1 ( int a ) _diagnose_if ( a = = 1 , " oh no " , " error " ) / / expected - note { { from ' diagnose_if ' } }
_diagnose_if ( a = = 1 , " nop " , " warning " ) ;
void errorWarnDiagnoseArg2 ( int a ) _diagnose_if ( a = = 1 , " oh no " , " error " ) / / expected - note { { from ' diagnose_if ' } }
_diagnose_if ( a = = 1 , " nop " , " error " ) ;
void errorWarnDiagnoseArg3 ( int a ) _diagnose_if ( a = = 1 , " nop " , " warning " )
_diagnose_if ( a = = 1 , " oh no " , " error " ) ; // expected-note{{from 'diagnose_if'}}
void runErrorWarnDiagnose ( ) {
errorWarnDiagnose1 ( ) ; // expected-error{{oh no}}
errorWarnDiagnose2 ( ) ; // expected-error{{oh no}}
errorWarnDiagnose3 ( ) ; // expected-error{{oh no}}
errorWarnDiagnoseArg1 ( 1 ) ; // expected-error{{oh no}}
errorWarnDiagnoseArg2 ( 1 ) ; // expected-error{{oh no}}
errorWarnDiagnoseArg3 ( 1 ) ; // expected-error{{oh no}}
}
void warnWarnDiagnose ( ) _diagnose_if ( 1 , " oh no! " , " warning " ) _diagnose_if ( 1 , " foo " , " warning " ) ; // expected-note 2{{from 'diagnose_if'}}
void runWarnWarnDiagnose ( ) {
warnWarnDiagnose ( ) ; // expected-warning{{oh no!}} expected-warning{{foo}}
}
void declsStackErr1 ( int a ) _diagnose_if ( a & 1 , " decl1 " , " error " ) ; // expected-note 2{{from 'diagnose_if'}}
void declsStackErr1 ( int a ) _diagnose_if ( a & 2 , " decl2 " , " error " ) ; // expected-note{{from 'diagnose_if'}}
void declsStackErr2 ( ) ;
void declsStackErr2 ( ) _diagnose_if ( 1 , " complaint " , " error " ) ; // expected-note{{from 'diagnose_if'}}
void declsStackErr3 ( ) _diagnose_if ( 1 , " complaint " , " error " ) ; // expected-note{{from 'diagnose_if'}}
void declsStackErr3 ( ) ;
void runDeclsStackErr ( ) {
declsStackErr1 ( 0 ) ;
declsStackErr1 ( 1 ) ; // expected-error{{decl1}}
declsStackErr1 ( 2 ) ; // expected-error{{decl2}}
declsStackErr1 ( 3 ) ; // expected-error{{decl1}}
declsStackErr2 ( ) ; // expected-error{{complaint}}
declsStackErr3 ( ) ; // expected-error{{complaint}}
}
void declsStackWarn1 ( int a ) _diagnose_if ( a & 1 , " decl1 " , " warning " ) ; // expected-note 2{{from 'diagnose_if'}}
void declsStackWarn1 ( int a ) _diagnose_if ( a & 2 , " decl2 " , " warning " ) ; // expected-note 2{{from 'diagnose_if'}}
void declsStackWarn2 ( ) ;
void declsStackWarn2 ( ) _diagnose_if ( 1 , " complaint " , " warning " ) ; // expected-note{{from 'diagnose_if'}}
void declsStackWarn3 ( ) _diagnose_if ( 1 , " complaint " , " warning " ) ; // expected-note{{from 'diagnose_if'}}
void declsStackWarn3 ( ) ;
void runDeclsStackWarn ( ) {
declsStackWarn1 ( 0 ) ;
declsStackWarn1 ( 1 ) ; // expected-warning{{decl1}}
declsStackWarn1 ( 2 ) ; // expected-warning{{decl2}}
declsStackWarn1 ( 3 ) ; // expected-warning{{decl1}} expected-warning{{decl2}}
declsStackWarn2 ( ) ; // expected-warning{{complaint}}
declsStackWarn3 ( ) ; // expected-warning{{complaint}}
}
void noMsg ( int n ) _diagnose_if ( n , " " , " warning " ) ; // expected-note{{from 'diagnose_if'}}
void runNoMsg ( ) {
noMsg ( 1 ) ; // expected-warning{{<no message provided>}}
}
void alwaysWarnWithArg ( int a ) _diagnose_if ( 1 | | a , " alwaysWarn " , " warning " ) ; // expected-note{{from 'diagnose_if'}}
void runAlwaysWarnWithArg ( int a ) {
alwaysWarnWithArg ( a ) ; // expected-warning{{alwaysWarn}}
}
2017-01-14 06:11:40 +08:00
// Test that diagnose_if warnings generated in system headers are not ignored.
# include "Inputs/diagnose-if-warn-system-header.h"
2017-07-01 06:33:24 +08:00
// Bug: we would complain about `a` being undeclared if this was spelled
// __diagnose_if__.
void underbarName ( int a ) __attribute__ ( ( __diagnose_if__ ( a , " " , " warning " ) ) ) ;