Reject inappropriate printf usage
This commit is contained in:
parent
51e328e538
commit
e8de74b8bf
49
SConstruct
49
SConstruct
|
@ -240,6 +240,55 @@ int A<int>::a();
|
||||||
'''
|
'''
|
||||||
self.Compile(context, text=text, msg='whether C++ compiler treats specializations as distinct', successflags=f)
|
self.Compile(context, text=text, msg='whether C++ compiler treats specializations as distinct', successflags=f)
|
||||||
@_custom_test
|
@_custom_test
|
||||||
|
def check_attribute_error(self,context):
|
||||||
|
"""
|
||||||
|
help:assume compiler supports __attribute__((error))
|
||||||
|
"""
|
||||||
|
f = '''
|
||||||
|
void a()__attribute__((__error__("a called")));
|
||||||
|
void b();
|
||||||
|
void b(){
|
||||||
|
%s
|
||||||
|
}
|
||||||
|
'''
|
||||||
|
if self.Compile(context, text=f % '', msg='whether compiler accepts function __attribute__((__error__))') and \
|
||||||
|
self.Compile(context, text=f % 'a();', msg='whether compiler understands function __attribute__((__error__))', expect_failure=True) and \
|
||||||
|
self.Compile(context, text=f % 'if("0"[0]==\'1\')a();', msg='whether compiler optimizes function __attribute__((__error__))'):
|
||||||
|
context.sconf.Define('DXX_HAVE_ATTRIBUTE_ERROR')
|
||||||
|
context.sconf.Define('__attribute_error(M)', '__attribute__((__error__(M)))')
|
||||||
|
else:
|
||||||
|
context.sconf.Define('__attribute_error(M)', self.comment_not_supported)
|
||||||
|
@_custom_test
|
||||||
|
def check_builtin_constant_p(self,context):
|
||||||
|
"""
|
||||||
|
help:assume compiler supports compile-time __builtin_constant_p
|
||||||
|
"""
|
||||||
|
f = '''
|
||||||
|
int c(int);
|
||||||
|
static inline int a(int b){
|
||||||
|
return __builtin_constant_p(b) ? 1 : %s;
|
||||||
|
}
|
||||||
|
int main(int argc, char **argv){
|
||||||
|
return a(1);
|
||||||
|
}
|
||||||
|
'''
|
||||||
|
if self.Compile(context, text=f % '2', msg='whether compiler accepts __builtin_constant_p') and \
|
||||||
|
self.Link(context, text=f % 'c(b)', msg='whether compiler optimizes __builtin_constant_p'):
|
||||||
|
context.sconf.Define('DXX_HAVE_BUILTIN_CONSTANT_P')
|
||||||
|
context.sconf.Define('dxx_builtin_constant_p(A)', '__builtin_constant_p(A)')
|
||||||
|
else:
|
||||||
|
context.sconf.Define('dxx_builtin_constant_p(A)', '((void)(A),0)')
|
||||||
|
@_custom_test
|
||||||
|
def check_embedded_compound_statement(self,context):
|
||||||
|
f = '''
|
||||||
|
int a();
|
||||||
|
int a(){
|
||||||
|
return ({ 1 + 2; });
|
||||||
|
}
|
||||||
|
'''
|
||||||
|
if self.Compile(context, text=f, msg='whether compiler understands embedded compound statements'):
|
||||||
|
context.sconf.Define('DXX_HAVE_EMBEDDED_COMPOUND_STATEMENT')
|
||||||
|
@_custom_test
|
||||||
def check_attribute_format_arg(self,context):
|
def check_attribute_format_arg(self,context):
|
||||||
"""
|
"""
|
||||||
help:assume compiler supports __attribute__((format_arg))
|
help:assume compiler supports __attribute__((format_arg))
|
||||||
|
|
|
@ -2,12 +2,27 @@
|
||||||
|
|
||||||
#include "dxxsconf.h"
|
#include "dxxsconf.h"
|
||||||
|
|
||||||
|
#if defined(DXX_HAVE_EMBEDDED_COMPOUND_STATEMENT)
|
||||||
|
#define _dxx_printf_raise_error(N,S) ( \
|
||||||
|
({ \
|
||||||
|
void N(void) __attribute_error(S); \
|
||||||
|
N(); \
|
||||||
|
}), 0)
|
||||||
|
#else
|
||||||
|
#define _dxx_printf_raise_error(N,S) (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
#define _dxx_call_printf_unwrap_args(...) , ## __VA_ARGS__
|
#define _dxx_call_printf_unwrap_args(...) , ## __VA_ARGS__
|
||||||
#define _dxx_call_printf_delete_comma2(A,...) __VA_ARGS__
|
#define _dxx_call_printf_delete_comma2(A,...) __VA_ARGS__
|
||||||
#define _dxx_call_printf_delete_comma(A,...) _dxx_call_printf_delete_comma2( A , ## __VA_ARGS__ )
|
#define _dxx_call_printf_delete_comma(A,...) _dxx_call_printf_delete_comma2( A , ## __VA_ARGS__ )
|
||||||
|
|
||||||
|
#define _dxx_printf_check_has_nontrivial_format_string(V,P,FMT) \
|
||||||
|
((void)((dxx_builtin_constant_p((FMT)) && (FMT)[0] == '%' && (FMT)[1] == 's' && (FMT)[2] == 0) && \
|
||||||
|
_dxx_printf_raise_error(dxx_trap_trivial_string_specifier_argument_##V, "bare %s argument to " #V "; use " #P " directly")))
|
||||||
|
|
||||||
#define dxx_call_printf_checked(V,P,A,FMT,...) \
|
#define dxx_call_printf_checked(V,P,A,FMT,...) \
|
||||||
( \
|
( \
|
||||||
|
_dxx_printf_check_has_nontrivial_format_string(V, P, FMT), \
|
||||||
(sizeof(#__VA_ARGS__) == 1) ? \
|
(sizeof(#__VA_ARGS__) == 1) ? \
|
||||||
(P(_dxx_call_printf_delete_comma(1 _dxx_call_printf_unwrap_args A, FMT))) : \
|
(P(_dxx_call_printf_delete_comma(1 _dxx_call_printf_unwrap_args A, FMT))) : \
|
||||||
(V(_dxx_call_printf_delete_comma(1 _dxx_call_printf_unwrap_args A, FMT) ,##__VA_ARGS__)) \
|
(V(_dxx_call_printf_delete_comma(1 _dxx_call_printf_unwrap_args A, FMT) ,##__VA_ARGS__)) \
|
||||||
|
|
Loading…
Reference in a new issue