Reject inappropriate printf usage

This commit is contained in:
Kp 2013-12-07 00:35:50 +00:00
parent 51e328e538
commit e8de74b8bf
2 changed files with 64 additions and 0 deletions

View file

@ -240,6 +240,55 @@ int A<int>::a();
'''
self.Compile(context, text=text, msg='whether C++ compiler treats specializations as distinct', successflags=f)
@_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):
"""
help:assume compiler supports __attribute__((format_arg))

View file

@ -2,12 +2,27 @@
#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_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,...) \
( \
_dxx_printf_check_has_nontrivial_format_string(V, P, FMT), \
(sizeof(#__VA_ARGS__) == 1) ? \
(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__)) \