mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-11-04 05:15:22 +00:00 
			
		
		
		
	
		
			
	
	
		
			82 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			82 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| 
								 | 
							
								dnl macro AST_CHECK_STRSEP_ARRAY_BOUNDS0
							 | 
						||
| 
								 | 
							
								dnl
							 | 
						||
| 
								 | 
							
								dnl The optimized strcmp and strsep macro's in
							 | 
						||
| 
								 | 
							
								dnl /usr/include/xxx-linux-gnu/bits/string2.h produce a warning (-Warray-bounds)
							 | 
						||
| 
								 | 
							
								dnl when compiled with clang (+ -O1), when the delimiter parameter is
							 | 
						||
| 
								 | 
							
								dnl passed in as a char *, instead of the expected char[]
							 | 
						||
| 
								 | 
							
								dnl
							 | 
						||
| 
								 | 
							
								dnl Instead of replacing all occurrences of strsep and strcmp, looking like:
							 | 
						||
| 
								 | 
							
								dnl xxx_name = strsep(&rest, ",");
							 | 
						||
| 
								 | 
							
								dnl
							 | 
						||
| 
								 | 
							
								dnl with:
							 | 
						||
| 
								 | 
							
								dnl char delimiters[] = ",";
							 | 
						||
| 
								 | 
							
								dnl xxx_name = strsep(&rest, delimiters);
							 | 
						||
| 
								 | 
							
								dnl
							 | 
						||
| 
								 | 
							
								dnl to get around this warning, without having to suppress the warning completely.
							 | 
						||
| 
								 | 
							
								dnl This macro detects the warning and force these 'optimizations' to be
							 | 
						||
| 
								 | 
							
								dnl switched off (Clang already has a set of builtin optimizers which should result
							 | 
						||
| 
								 | 
							
								dnl in good performance for these type of functions).
							 | 
						||
| 
								 | 
							
								dnl
							 | 
						||
| 
								 | 
							
								dnl When the issue is detected it will add a define to autoconfig.h which will prevent
							 | 
						||
| 
								 | 
							
								dnl bits/string2.h from replacing the standard implementation of strsep/strcmp with it's
							 | 
						||
| 
								 | 
							
								dnl macro optimized version. bits/string.h checks these defines before inserting it's
							 | 
						||
| 
								 | 
							
								dnl replacements.
							 | 
						||
| 
								 | 
							
								dnl
							 | 
						||
| 
								 | 
							
								dnl When bits/string2.h get's fixed in the future, this macro should be able to
							 | 
						||
| 
								 | 
							
								dnl detect the new behaviour, and when no warning is generated, it will use the optimize
							 | 
						||
| 
								 | 
							
								dnl version from bits/string2.h
							 | 
						||
| 
								 | 
							
								dnl
							 | 
						||
| 
								 | 
							
								dnl
							 | 
						||
| 
								 | 
							
								dnl See 'define __strcmp_gc(s1, s2, l2) in bits/string2.h'
							 | 
						||
| 
								 | 
							
								dnl
							 | 
						||
| 
								 | 
							
								dnl llvm-comment: Normally, this array-bounds warning are suppressed for macros, so that
							 | 
						||
| 
								 | 
							
								dnl unused paths like the one that accesses __s1[3] are not warned about.  But if you
							 | 
						||
| 
								 | 
							
								dnl preprocess manually, and feed the result to another instance of clang, it will warn
							 | 
						||
| 
								 | 
							
								dnl about all the possible forks of this particular if statement.
							 | 
						||
| 
								 | 
							
								dnl
							 | 
						||
| 
								 | 
							
								dnl Instead of switching of this optimization, another solution would be to run the pre-
							 | 
						||
| 
								 | 
							
								dnl processing step with -frewrite-includes, which should preserve enough information
							 | 
						||
| 
								 | 
							
								dnl so that clang should still be able to suppress the diagnostic at the compile step
							 | 
						||
| 
								 | 
							
								dnl later on.
							 | 
						||
| 
								 | 
							
								dnl
							 | 
						||
| 
								 | 
							
								dnl See also "https://llvm.org/bugs/show_bug.cgi?id=20144"
							 | 
						||
| 
								 | 
							
								dnl See also "https://llvm.org/bugs/show_bug.cgi?id=11536"
							 | 
						||
| 
								 | 
							
								dnl
							 | 
						||
| 
								 | 
							
								AC_DEFUN([AST_CHECK_STRSEP_ARRAY_BOUNDS], [
							 | 
						||
| 
								 | 
							
									AC_MSG_CHECKING([for clang strsep/strcmp optimization])
							 | 
						||
| 
								 | 
							
									save_CFLAGS="$CFLAGS"
							 | 
						||
| 
								 | 
							
									CFLAGS="$CFLAGS -O1 -Werror=array-bounds"
							 | 
						||
| 
								 | 
							
									AC_COMPILE_IFELSE(
							 | 
						||
| 
								 | 
							
										[
							 | 
						||
| 
								 | 
							
										    	AC_LANG_SOURCE([
							 | 
						||
| 
								 | 
							
												#include <stdio.h>
							 | 
						||
| 
								 | 
							
												#include <string.h>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												/* fails with clang and -O1 */
							 | 
						||
| 
								 | 
							
												void test_strsep_strcmp (void) {
							 | 
						||
| 
								 | 
							
													char *haystackstr = "test1,test2";
							 | 
						||
| 
								 | 
							
													char *outstr;
							 | 
						||
| 
								 | 
							
													if (!strcmp(haystackstr, ",")) {
							 | 
						||
| 
								 | 
							
														printf("fail\n");
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
													if ((outstr = strsep(&haystackstr, ","))) {
							 | 
						||
| 
								 | 
							
														printf("fail:%s\n", outstr);
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												int main(int argc, char *argv[]) {
							 | 
						||
| 
								 | 
							
													test_strsep_strcmp();
							 | 
						||
| 
								 | 
							
													return 0;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											])
							 | 
						||
| 
								 | 
							
										],[
							 | 
						||
| 
								 | 
							
											AC_MSG_RESULT(no)
							 | 
						||
| 
								 | 
							
										],[
							 | 
						||
| 
								 | 
							
											dnl setting this define in autoconfig.h will prevent bits/string2.h from replacing the standard implementation of strsep/strcmp
							 | 
						||
| 
								 | 
							
											AC_DEFINE([_HAVE_STRING_ARCH_strcmp], 1, [Prevent clang array-bounds warning by not using strcmp from bits/string2.h])
							 | 
						||
| 
								 | 
							
											AC_DEFINE([_HAVE_STRING_ARCH_strsep], 1, [Prevent clang array-bounds warning by not using strsep from bits/string2.h])
							 | 
						||
| 
								 | 
							
											AC_MSG_RESULT([prevent use of __string2_1bptr_p / strsep / strcmp from bits/string2.h])
							 | 
						||
| 
								 | 
							
										]
							 | 
						||
| 
								 | 
							
									)
							 | 
						||
| 
								 | 
							
									CFLAGS="$save_CFLAGS"
							 | 
						||
| 
								 | 
							
								])
							 |