From 01e95341203049e57915f5ad9d8102c909364473 Mon Sep 17 00:00:00 2001 From: Chan Lee Date: Thu, 1 Jun 2017 12:28:22 +0900 Subject: [PATCH 01/16] packaging: enable log_exe_name sanitizer option for ASan This option shoule be 'log_exe_name' not 'log_exe_path' According to SanitizerCommonFlags, (https://github.com/google/sanitizers/wiki/SanitizerCommonFlags) Enabling this option makes ASan mention name of executable when reporting error and append executable name to logs (as in "log_path.exe_name.pid"). Change-Id: I0a49a2032355b6527ea7522faa1414ec8d567125 Signed-off-by: Chan Lee --- packaging/gcc-aarch64.spec | 2 +- packaging/gcc-armv7l.spec | 2 +- packaging/linaro-gcc.spec | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packaging/gcc-aarch64.spec b/packaging/gcc-aarch64.spec index af6e10c..40d1ae6 100644 --- a/packaging/gcc-aarch64.spec +++ b/packaging/gcc-aarch64.spec @@ -785,7 +785,7 @@ Asan runtime environment echo "%{libdir}/libasan.so" > /etc/ld.so.preload [ -f /etc/ld.so.preload.orig ] && cat /etc/ld.so.preload.orig >> /etc/ld.so.preload [ -f /etc/ld.so.preload.orig ] && rm -f /etc/ld.so.preload.orig -echo "halt_on_error=false:start_deactivated=true:print_cmdline=true:quarantine_size_mb=1:detect_leaks=0:log_path=/tmp/asan.log:log_exe_path=1" > /ASAN_OPTIONS +echo "halt_on_error=false:start_deactivated=true:print_cmdline=true:quarantine_size_mb=1:detect_leaks=0:log_path=/tmp/asan.log:log_exe_name=1" > /ASAN_OPTIONS chsmack -a "_" /etc/ld.so.preload /ASAN_OPTIONS %preun -n asan-runtime-env diff --git a/packaging/gcc-armv7l.spec b/packaging/gcc-armv7l.spec index 9b816c1..f3ad3bd 100644 --- a/packaging/gcc-armv7l.spec +++ b/packaging/gcc-armv7l.spec @@ -785,7 +785,7 @@ Asan runtime environment echo "%{libdir}/libasan.so" > /etc/ld.so.preload [ -f /etc/ld.so.preload.orig ] && cat /etc/ld.so.preload.orig >> /etc/ld.so.preload [ -f /etc/ld.so.preload.orig ] && rm -f /etc/ld.so.preload.orig -echo "halt_on_error=false:start_deactivated=true:print_cmdline=true:quarantine_size_mb=1:detect_leaks=0:log_path=/tmp/asan.log:log_exe_path=1" > /ASAN_OPTIONS +echo "halt_on_error=false:start_deactivated=true:print_cmdline=true:quarantine_size_mb=1:detect_leaks=0:log_path=/tmp/asan.log:log_exe_name=1" > /ASAN_OPTIONS chsmack -a "_" /etc/ld.so.preload /ASAN_OPTIONS %preun -n asan-runtime-env diff --git a/packaging/linaro-gcc.spec b/packaging/linaro-gcc.spec index d0e2220..c6460cf 100644 --- a/packaging/linaro-gcc.spec +++ b/packaging/linaro-gcc.spec @@ -782,7 +782,7 @@ Asan runtime environment echo "%{libdir}/libasan.so" > /etc/ld.so.preload [ -f /etc/ld.so.preload.orig ] && cat /etc/ld.so.preload.orig >> /etc/ld.so.preload [ -f /etc/ld.so.preload.orig ] && rm -f /etc/ld.so.preload.orig -echo "halt_on_error=false:start_deactivated=true:print_cmdline=true:quarantine_size_mb=1:detect_leaks=0:log_path=/tmp/asan.log:log_exe_path=1" > /ASAN_OPTIONS +echo "halt_on_error=false:start_deactivated=true:print_cmdline=true:quarantine_size_mb=1:detect_leaks=0:log_path=/tmp/asan.log:log_exe_name=1" > /ASAN_OPTIONS chsmack -a "_" /etc/ld.so.preload /ASAN_OPTIONS %preun -n asan-runtime-env -- 2.7.4 From 10747d7c26bb7c0c4e2e8761256e44b82e63f47a Mon Sep 17 00:00:00 2001 From: Denis Khalikov Date: Thu, 8 Jun 2017 11:32:02 +0300 Subject: [PATCH 02/16] [asan] Fix ASan preload issue. There might be a situation when ASan initializing later than shared library which has malloc in static constructor. (rtld doesn't provide the order of initiazation) In this case ASan doesn't initialize interceptors but already intercepting malloc. If malloc is too big to be handled by static local pool ASan will die with error: Sanitizer CHECK failed: libsanitizer/asan/asan_malloc_linux.cc:40 ((allocated_for_dlsym)) < ((kDlsymAllocPoolSize)) (1036, 1024) Backported from LLVM mainline rL305058 Change-Id: I93c9662953629b373506fcacacee43edd791c68f Signed-off-by: Denis Khalikov --- libsanitizer/asan/asan_malloc_linux.cc | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/libsanitizer/asan/asan_malloc_linux.cc b/libsanitizer/asan/asan_malloc_linux.cc index bfe72af..24829ef 100644 --- a/libsanitizer/asan/asan_malloc_linux.cc +++ b/libsanitizer/asan/asan_malloc_linux.cc @@ -56,30 +56,42 @@ INTERCEPTOR(void, cfree, void *ptr) { } INTERCEPTOR(void*, malloc, uptr size) { - if (UNLIKELY(!asan_inited)) + if (UNLIKELY(asan_init_is_running)) // Hack: dlsym calls malloc before REAL(malloc) is retrieved from dlsym. return AllocateFromLocalPool(size); + ENSURE_ASAN_INITED(); GET_STACK_TRACE_MALLOC; return asan_malloc(size, &stack); } INTERCEPTOR(void*, calloc, uptr nmemb, uptr size) { - if (UNLIKELY(!asan_inited)) + if (UNLIKELY(asan_init_is_running)) // Hack: dlsym calls calloc before REAL(calloc) is retrieved from dlsym. return AllocateFromLocalPool(nmemb * size); + ENSURE_ASAN_INITED(); GET_STACK_TRACE_MALLOC; return asan_calloc(nmemb, size, &stack); } INTERCEPTOR(void*, realloc, void *ptr, uptr size) { - GET_STACK_TRACE_MALLOC; if (UNLIKELY(IsInDlsymAllocPool(ptr))) { - uptr offset = (uptr)ptr - (uptr)alloc_memory_for_dlsym; - uptr copy_size = Min(size, kDlsymAllocPoolSize - offset); - void *new_ptr = asan_malloc(size, &stack); + const uptr offset = (uptr)ptr - (uptr)alloc_memory_for_dlsym; + const uptr copy_size = Min(size, kDlsymAllocPoolSize - offset); + void *new_ptr; + if (UNLIKELY(asan_init_is_running)) { + new_ptr = AllocateFromLocalPool(size); + } else { + ENSURE_ASAN_INITED(); + GET_STACK_TRACE_MALLOC; + new_ptr = asan_malloc(size, &stack); + } internal_memcpy(new_ptr, ptr, copy_size); return new_ptr; } + if (UNLIKELY(asan_init_is_running)) + return AllocateFromLocalPool(size); + ENSURE_ASAN_INITED(); + GET_STACK_TRACE_MALLOC; return asan_realloc(ptr, size, &stack); } -- 2.7.4 From 0b7063a7415d107715e262ed8b9a03ff14af223e Mon Sep 17 00:00:00 2001 From: Denis Khalikov Date: Mon, 29 May 2017 20:35:03 +0300 Subject: [PATCH 03/16] [ubsan] Fix for vptr check MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Summary: There can be a situation when vptr not initializing by constructor of the object, and has a junk data which should be properly checked, because c++ standard says: "If the new-initializer is omitted, the object is default-initialized (8.5). [ Note: If no initialization is performed, the object has an indeterminate value. — end note ] Change-Id: I6fd297dc10b2ddb54eaed9e6eb3a46310dafead4 Signed-off-by: Denis Khalikov --- gcc/testsuite/g++.dg/ubsan/pr332211-llvm.C | 21 +++++++++++++++++++++ libsanitizer/ubsan/ubsan_type_hash_itanium.cc | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/ubsan/pr332211-llvm.C diff --git a/gcc/testsuite/g++.dg/ubsan/pr332211-llvm.C b/gcc/testsuite/g++.dg/ubsan/pr332211-llvm.C new file mode 100644 index 0000000..c747754 --- /dev/null +++ b/gcc/testsuite/g++.dg/ubsan/pr332211-llvm.C @@ -0,0 +1,21 @@ +/* PR 332211 port from llvm */ +/* { dg-do run } */ +/* { dg-options "-fsanitize=vptr -frtti -fno-sanitize-recover=undefined"} */ + +class Base { +public: + int i; + virtual void print() {} +}; + +class Derived : public Base { +public: + void print() {} +}; + +int main() { + char *c = new char[sizeof(Derived)]; + Derived *list = (Derived *)c; + int foo = list->i; + return 0; +} diff --git a/libsanitizer/ubsan/ubsan_type_hash_itanium.cc b/libsanitizer/ubsan/ubsan_type_hash_itanium.cc index e4f1334..4716935 100644 --- a/libsanitizer/ubsan/ubsan_type_hash_itanium.cc +++ b/libsanitizer/ubsan/ubsan_type_hash_itanium.cc @@ -191,7 +191,7 @@ struct VtablePrefix { }; VtablePrefix *getVtablePrefix(void *Vtable) { VtablePrefix *Vptr = reinterpret_cast(Vtable); - if (!Vptr) + if (!IsAccessibleMemoryRange((uptr)Vptr, sizeof(VtablePrefix))) return 0; VtablePrefix *Prefix = Vptr - 1; if (!Prefix->TypeInfo) -- 2.7.4 From 6da83d4adc857ba1c4370b2b8f32825d5cb13ebe Mon Sep 17 00:00:00 2001 From: jakub Date: Tue, 25 Apr 2017 16:47:32 +0000 Subject: [PATCH 04/16] PR target/77728 * config/arm/arm.c: Include gimple.h. (aapcs_layout_arg): Emit -Wpsabi note if arm_needs_doubleword_align returns negative, increment ncrn only if it returned positive. (arm_needs_doubleword_align): Return int instead of bool, ignore DECL_ALIGN of non-FIELD_DECL TYPE_FIELDS chain members, but if there is any such non-FIELD_DECL > PARM_BOUNDARY aligned decl, return -1 instead of false. (arm_function_arg): Emit -Wpsabi note if arm_needs_doubleword_align returns negative, increment nregs only if it returned positive. (arm_setup_incoming_varargs): Likewise. (arm_function_arg_boundary): Emit -Wpsabi note if arm_needs_doubleword_align returns negative, return DOUBLEWORD_ALIGNMENT only if it returned positive. testsuite/ * g++.dg/abi/pr77728-1.C: New test. Backported from trunk: 0e6ba620ce829dbde3ece9cefdbe09355ddfbb74 Change-Id: Ia454a63c3ebb930e546188ded5f339a967d81754 git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-7-branch@247259 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/config/arm/arm.c | 78 ++++++++++++---- gcc/testsuite/g++.dg/abi/pr77728-1.C | 171 +++++++++++++++++++++++++++++++++++ 2 files changed, 232 insertions(+), 17 deletions(-) create mode 100644 gcc/testsuite/g++.dg/abi/pr77728-1.C diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index ddca3b0..5ab94d9 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -63,6 +63,7 @@ #include "tm-constrs.h" #include "rtl-iter.h" #include "gimplify.h" +#include "gimple.h" /* This file should be included last. */ #include "target-def.h" @@ -80,7 +81,7 @@ struct four_ints /* Forward function declarations. */ static bool arm_const_not_ok_for_debug_p (rtx); -static bool arm_needs_doubleword_align (machine_mode, const_tree); +static int arm_needs_doubleword_align (machine_mode, const_tree); static int arm_compute_static_chain_stack_bytes (void); static arm_stack_offsets *arm_get_frame_offsets (void); static void arm_add_gc_roots (void); @@ -6204,8 +6205,20 @@ aapcs_layout_arg (CUMULATIVE_ARGS *pcum, machine_mode mode, /* C3 - For double-word aligned arguments, round the NCRN up to the next even number. */ ncrn = pcum->aapcs_ncrn; - if ((ncrn & 1) && arm_needs_doubleword_align (mode, type)) - ncrn++; + if (ncrn & 1) + { + int res = arm_needs_doubleword_align (mode, type); + /* Only warn during RTL expansion of call stmts, otherwise we would + warn e.g. during gimplification even on functions that will be + always inlined, and we'd warn multiple times. Don't warn when + called in expand_function_start either, as we warn instead in + arm_function_arg_boundary in that case. */ + if (res < 0 && warn_psabi && currently_expanding_gimple_stmt) + inform (input_location, "parameter passing for argument of type " + "%qT changed in GCC 7.1", type); + else if (res > 0) + ncrn++; + } nregs = ARM_NUM_REGS2(mode, type); @@ -6310,12 +6323,16 @@ arm_init_cumulative_args (CUMULATIVE_ARGS *pcum, tree fntype, } } -/* Return true if mode/type need doubleword alignment. */ -static bool +/* Return 1 if double word alignment is required for argument passing. + Return -1 if double word alignment used to be required for argument + passing before PR77728 ABI fix, but is not required anymore. + Return 0 if double word alignment is not required and wasn't requried + before either. */ +static int arm_needs_doubleword_align (machine_mode mode, const_tree type) { if (!type) - return PARM_BOUNDARY < GET_MODE_ALIGNMENT (mode); + return GET_MODE_ALIGNMENT (mode) > PARM_BOUNDARY; /* Scalar and vector types: Use natural alignment, i.e. of base type. */ if (!AGGREGATE_TYPE_P (type)) @@ -6325,12 +6342,21 @@ arm_needs_doubleword_align (machine_mode mode, const_tree type) if (TREE_CODE (type) == ARRAY_TYPE) return TYPE_ALIGN (TREE_TYPE (type)) > PARM_BOUNDARY; + int ret = 0; /* Record/aggregate types: Use greatest member alignment of any member. */ for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) if (DECL_ALIGN (field) > PARM_BOUNDARY) - return true; + { + if (TREE_CODE (field) == FIELD_DECL) + return 1; + else + /* Before PR77728 fix, we were incorrectly considering also + other aggregate fields, like VAR_DECLs, TYPE_DECLs etc. + Make sure we can warn about that with -Wpsabi. */ + ret = -1; + } - return false; + return ret; } @@ -6387,10 +6413,15 @@ arm_function_arg (cumulative_args_t pcum_v, machine_mode mode, } /* Put doubleword aligned quantities in even register pairs. */ - if (pcum->nregs & 1 - && ARM_DOUBLEWORD_ALIGN - && arm_needs_doubleword_align (mode, type)) - pcum->nregs++; + if ((pcum->nregs & 1) && ARM_DOUBLEWORD_ALIGN) + { + int res = arm_needs_doubleword_align (mode, type); + if (res < 0 && warn_psabi) + inform (input_location, "parameter passing for argument of type " + "%qT changed in GCC 7.1", type); + else if (res > 0) + pcum->nregs++; + } /* Only allow splitting an arg between regs and memory if all preceding args were allocated to regs. For args passed by reference we only count @@ -6409,9 +6440,15 @@ arm_function_arg (cumulative_args_t pcum_v, machine_mode mode, static unsigned int arm_function_arg_boundary (machine_mode mode, const_tree type) { - return (ARM_DOUBLEWORD_ALIGN && arm_needs_doubleword_align (mode, type) - ? DOUBLEWORD_ALIGNMENT - : PARM_BOUNDARY); + if (!ARM_DOUBLEWORD_ALIGN) + return PARM_BOUNDARY; + + int res = arm_needs_doubleword_align (mode, type); + if (res < 0 && warn_psabi) + inform (input_location, "parameter passing for argument of type %qT " + "changed in GCC 7.1", type); + + return res > 0 ? DOUBLEWORD_ALIGNMENT : PARM_BOUNDARY; } static int @@ -26302,8 +26339,15 @@ arm_setup_incoming_varargs (cumulative_args_t pcum_v, if (pcum->pcs_variant <= ARM_PCS_AAPCS_LOCAL) { nregs = pcum->aapcs_ncrn; - if ((nregs & 1) && arm_needs_doubleword_align (mode, type)) - nregs++; + if (nregs & 1) + { + int res = arm_needs_doubleword_align (mode, type); + if (res < 0 && warn_psabi) + inform (input_location, "parameter passing for argument of " + "type %qT changed in GCC 7.1", type); + else if (res > 0) + nregs++; + } } else nregs = pcum->nregs; diff --git a/gcc/testsuite/g++.dg/abi/pr77728-1.C b/gcc/testsuite/g++.dg/abi/pr77728-1.C new file mode 100644 index 0000000..05f08c9 --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/pr77728-1.C @@ -0,0 +1,171 @@ +// { dg-do compile { target arm_eabi } } +// { dg-options "-Wpsabi" } + +#include + +template +struct A { double p; }; + +A<0> v; + +template +struct B +{ + typedef A T; + int i, j; +}; + +struct C : public B<0> {}; +struct D {}; +struct E : public D, C {}; +struct F : public B<1> {}; +struct G : public F { static double y; }; +struct H : public G {}; +struct I : public D { long long z; }; +struct J : public D { static double z; int i, j; }; + +template +struct K : public D { typedef A T; int i, j; }; + +struct L { static double h; int i, j; }; + +int +fn1 (int a, B<0> b) // { dg-message "note: parameter passing for argument of type \[^\n\r]* changed in GCC 7\.1" } +{ + return a + b.i; +} + +int +fn2 (int a, B<1> b) +{ + return a + b.i; +} + +int +fn3 (int a, L b) // { dg-message "note: parameter passing for argument of type \[^\n\r]* changed in GCC 7\.1" } +{ + return a + b.i; +} + +int +fn4 (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m, B<0> n, ...) +// { dg-message "note: parameter passing for argument of type \[^\n\r]* changed in GCC 7\.1" "" { target *-*-* } .-1 } +{ + va_list ap; + va_start (ap, n); + int x = va_arg (ap, int); + va_end (ap); + return x; +} + +int +fn5 (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m, B<1> n, ...) +{ + va_list ap; + va_start (ap, n); + int x = va_arg (ap, int); + va_end (ap); + return x; +} + +int +fn6 (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m, C n, ...) +{ + va_list ap; + va_start (ap, n); + int x = va_arg (ap, int); + va_end (ap); + return x; +} + +int +fn7 (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m, E n, ...) +{ + va_list ap; + va_start (ap, n); + int x = va_arg (ap, int); + va_end (ap); + return x; +} + +int +fn8 (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m, H n, ...) +{ + va_list ap; + va_start (ap, n); + int x = va_arg (ap, int); + va_end (ap); + return x; +} + +int +fn9 (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m, I n, ...) +{ + va_list ap; + va_start (ap, n); + int x = va_arg (ap, int); + va_end (ap); + return x; +} + +int +fn10 (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m, J n, ...) +// { dg-message "note: parameter passing for argument of type \[^\n\r]* changed in GCC 7\.1" "" { target *-*-* } .-1 } +{ + va_list ap; + va_start (ap, n); + int x = va_arg (ap, int); + va_end (ap); + return x; +} + +int +fn11 (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m, K<0> n, ...) +// { dg-message "note: parameter passing for argument of type \[^\n\r]* changed in GCC 7\.1" "" { target *-*-* } .-1 } +{ + va_list ap; + va_start (ap, n); + int x = va_arg (ap, int); + va_end (ap); + return x; +} + +int +fn12 (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m, K<2> n, ...) +{ + va_list ap; + va_start (ap, n); + int x = va_arg (ap, int); + va_end (ap); + return x; +} + +void +test () +{ + static B<0> b0; + static B<1> b1; + static L l; + static C c; + static E e; + static H h; + static I i; + static J j; + static K<0> k0; + static K<2> k2; + fn1 (1, b0); // { dg-message "note: parameter passing for argument of type \[^\n\r]* changed in GCC 7\.1" } + fn2 (1, b1); + fn3 (1, l); // { dg-message "note: parameter passing for argument of type \[^\n\r]* changed in GCC 7\.1" } + fn4 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, b0, 1, 2, 3, 4); + // { dg-message "note: parameter passing for argument of type \[^\n\r]* changed in GCC 7\.1" "" { target *-*-* } .-1 } + fn5 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, b1, 1, 2, 3, 4); + fn6 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, c, 1, 2, 3, 4); + fn7 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, e, 1, 2, 3, 4); + fn8 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, h, 1, 2, 3, 4); + fn9 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, i, 1, 2, 3, 4); + fn10 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, j, 1, 2, 3, 4); + // { dg-message "note: parameter passing for argument of type \[^\n\r]* changed in GCC 7\.1" "" { target *-*-* } .-1 } + fn11 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, k0, 1, 2, 3, 4); + // { dg-message "note: parameter passing for argument of type \[^\n\r]* changed in GCC 7\.1" "" { target *-*-* } .-1 } + fn12 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, k2, 1, 2, 3, 4); +} -- 2.7.4 From 1d929c7915bcb563f39c0012b752572428958186 Mon Sep 17 00:00:00 2001 From: Mikhail Kashkarov Date: Thu, 15 Jun 2017 17:03:07 +0300 Subject: [PATCH 05/16] Implement AAPCS64 updates for alignment attribute. PR target/77728 gcc/ * config/aarch64/aarch64.c(aarch64_function_arg_alignmentq): Rewrite, looking one level down for records and arrays. Ignore TYPE_FIELDS chain decls other than FIELD_DECLs. (aarch64_layout_arg): Adjust aarch64_function_arg_alignment caller. (aarch64_function_arg_boundary): Likewise. Simplify using MIN/MAX. (aarch64_gimplify_va_arg_expr): Adjust aarch64_function_arg_alignment caller. testsuite/ * g++.dg/abi/pr77728-2.C: New test. Backported from trunk: be35fa06e8f976e1cb880988d5c82813106922fd 32cb614ad1f60267f914e38da26a73259299d720 26312b0ea5f3dfc6e3d8d8d18c76d464d6fa328e Change-Id: I4293167468353e9730dc918b87edda4484af8315 --- gcc/config/aarch64/aarch64.c | 54 ++++++------ gcc/testsuite/g++.dg/abi/pr77728-2.C | 165 +++++++++++++++++++++++++++++++++++ 2 files changed, 193 insertions(+), 26 deletions(-) create mode 100644 gcc/testsuite/g++.dg/abi/pr77728-2.C diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index f0970f2..bd75ef2 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -2246,22 +2246,24 @@ aarch64_vfp_is_call_candidate (cumulative_args_t pcum_v, machine_mode mode, static unsigned int aarch64_function_arg_alignment (machine_mode mode, const_tree type) { - unsigned int alignment; + if (!type) + return GET_MODE_ALIGNMENT (mode); - if (type) - { - if (!integer_zerop (TYPE_SIZE (type))) - { - if (TYPE_MODE (type) == mode) - alignment = TYPE_ALIGN (type); - else - alignment = GET_MODE_ALIGNMENT (mode); - } - else - alignment = 0; - } - else - alignment = GET_MODE_ALIGNMENT (mode); + if (integer_zerop (TYPE_SIZE (type))) + return 0; + + gcc_assert (TYPE_MODE (type) == mode); + + if (!AGGREGATE_TYPE_P (type)) + return TYPE_ALIGN (TYPE_MAIN_VARIANT (type)); + + if (TREE_CODE (type) == ARRAY_TYPE) + return TYPE_ALIGN (TREE_TYPE (type)); + + unsigned int alignment = 0; + for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) + if (TREE_CODE (field) == FIELD_DECL) + alignment = std::max (alignment, DECL_ALIGN (field)); return alignment; } @@ -2350,24 +2352,28 @@ aarch64_layout_arg (cumulative_args_t pcum_v, machine_mode mode, entirely general registers. */ if (allocate_ncrn && (ncrn + nregs <= NUM_ARG_REGS)) { - unsigned int alignment = aarch64_function_arg_alignment (mode, type); gcc_assert (nregs == 0 || nregs == 1 || nregs == 2); /* C.8 if the argument has an alignment of 16 then the NGRN is rounded up to the next even number. */ - if (nregs == 2 && alignment == 16 * BITS_PER_UNIT && ncrn % 2) + if (nregs == 2 + && ncrn % 2 + /* The == 16 * BITS_PER_UNIT instead of >= 16 * BITS_PER_UNIT + comparison is there because for > 16 * BITS_PER_UNIT + alignment nregs should be > 2 and therefore it should be + passed by reference rather than value. */ + && aarch64_function_arg_alignment (mode, type) == 16 * BITS_PER_UNIT) { ++ncrn; gcc_assert (ncrn + nregs <= NUM_ARG_REGS); } + /* NREGS can be 0 when e.g. an empty structure is to be passed. A reg is still generated for it, but the caller should be smart enough not to use it. */ if (nregs == 0 || nregs == 1 || GET_MODE_CLASS (mode) == MODE_INT) - { - pcum->aapcs_reg = gen_rtx_REG (mode, R0_REGNUM + ncrn); - } + pcum->aapcs_reg = gen_rtx_REG (mode, R0_REGNUM + ncrn); else { rtx par; @@ -2395,6 +2401,7 @@ aarch64_layout_arg (cumulative_args_t pcum_v, machine_mode mode, this argument and align the total size if necessary. */ on_stack: pcum->aapcs_stack_words = size / UNITS_PER_WORD; + if (aarch64_function_arg_alignment (mode, type) == 16 * BITS_PER_UNIT) pcum->aapcs_stack_size = ROUND_UP (pcum->aapcs_stack_size, 16 / UNITS_PER_WORD); @@ -2487,12 +2494,7 @@ static unsigned int aarch64_function_arg_boundary (machine_mode mode, const_tree type) { unsigned int alignment = aarch64_function_arg_alignment (mode, type); - - if (alignment < PARM_BOUNDARY) - alignment = PARM_BOUNDARY; - if (alignment > STACK_BOUNDARY) - alignment = STACK_BOUNDARY; - return alignment; + return MIN (MAX (alignment, PARM_BOUNDARY), STACK_BOUNDARY); } /* For use by FUNCTION_ARG_PADDING (MODE, TYPE). diff --git a/gcc/testsuite/g++.dg/abi/pr77728-2.C b/gcc/testsuite/g++.dg/abi/pr77728-2.C new file mode 100644 index 0000000..ffe6910 --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/pr77728-2.C @@ -0,0 +1,165 @@ +// { dg-do compile { target { { aarch64-*-* } && c++11 } } } +// { dg-options "" } + +#include + +template +struct alignas (16) A { char p[16]; }; + +A<0> v; + +template +struct B +{ + typedef A T; + int i, j, k, l; +}; + +struct C : public B<0> {}; +struct D {}; +struct E : public D, C {}; +struct F : public B<1> {}; +struct G : public F { static int y alignas (16); }; +struct H : public G {}; +struct I : public D { int z alignas (16); }; +struct J : public D { static int z alignas (16); int i, j, k, l; }; + +template +struct K : public D { typedef A T; int i, j; }; + +struct L { static int h alignas (16); int i, j, k, l; }; + +int +fn1 (int a, B<0> b) +{ + return a + b.i; +} + +int +fn2 (int a, B<1> b) +{ + return a + b.i; +} + +int +fn3 (int a, L b) +{ + return a + b.i; +} + +int +fn4 (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m, B<0> n, ...) +{ + va_list ap; + va_start (ap, n); + int x = va_arg (ap, int); + va_end (ap); + return x; +} + +int +fn5 (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m, B<1> n, ...) +{ + va_list ap; + va_start (ap, n); + int x = va_arg (ap, int); + va_end (ap); + return x; +} + +int +fn6 (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m, C n, ...) +{ + va_list ap; + va_start (ap, n); + int x = va_arg (ap, int); + va_end (ap); + return x; +} + +int +fn7 (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m, E n, ...) +{ + va_list ap; + va_start (ap, n); + int x = va_arg (ap, int); + va_end (ap); + return x; +} + +int +fn8 (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m, H n, ...) +{ + va_list ap; + va_start (ap, n); + int x = va_arg (ap, int); + va_end (ap); + return x; +} + +int +fn9 (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m, I n, ...) +{ + va_list ap; + va_start (ap, n); + int x = va_arg (ap, int); + va_end (ap); + return x; +} + +int +fn10 (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m, J n, ...) +{ + va_list ap; + va_start (ap, n); + int x = va_arg (ap, int); + va_end (ap); + return x; +} + +int +fn11 (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m, K<0> n, ...) +{ + va_list ap; + va_start (ap, n); + int x = va_arg (ap, int); + va_end (ap); + return x; +} + +int +fn12 (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m, K<2> n, ...) +{ + va_list ap; + va_start (ap, n); + int x = va_arg (ap, int); + va_end (ap); + return x; +} + +void +test () +{ + static B<0> b0; + static B<1> b1; + static L l; + static C c; + static E e; + static H h; + static I i; + static J j; + static K<0> k0; + static K<2> k2; + fn1 (1, b0); + fn2 (1, b1); + fn3 (1, l); + fn4 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, b0, 1, 2, 3, 4); + fn5 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, b1, 1, 2, 3, 4); + fn6 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, c, 1, 2, 3, 4); + fn7 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, e, 1, 2, 3, 4); + fn8 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, h, 1, 2, 3, 4); + fn9 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, i, 1, 2, 3, 4); + fn10 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, j, 1, 2, 3, 4); + fn11 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, k0, 1, 2, 3, 4); + fn12 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, k2, 1, 2, 3, 4); +} -- 2.7.4 From 1bee23a5afa1e59d348d3ebb1dc81cc209978a2b Mon Sep 17 00:00:00 2001 From: Mikhail Kashkarov Date: Thu, 15 Jun 2017 19:47:33 +0300 Subject: [PATCH 06/16] Tests of AAPCS64 updates for alignment attribute gcc/testsuite/ * gcc.target/aarch64/aapcs64/aapcs64.exp: Also execute rec_*.c * gcc.target/aarch64/aapcs64/rec_align-5.c: New. * gcc.target/aarch64/aapcs64/rec_align-6.c: New. * gcc.target/aarch64/aapcs64/rec_align-7.c: New. * gcc.target/aarch64/aapcs64/rec_align-8.c: New. * gcc.target/aarch64/aapcs64/rec_align-9.c: New. * gcc.target/aarch64/aapcs64/test_align-5.c: New. * gcc.target/aarch64/aapcs64/test_align-6.c: New. * gcc.target/aarch64/aapcs64/test_align-7.c: New. * gcc.target/aarch64/aapcs64/test_align-8.c: New. * gcc.target/aarch64/aapcs64/test_align-9.c: New. * gcc.target/aarch64/aapcs64/rec_vaarg-1.c: New. * gcc.target/aarch64/aapcs64/rec_vaarg-2.c: New. Backported from trunk: 84ee090575f413f92377812d277b705d023a4b0b Change-Id: Idf931ee8b3b5f556b7341734eb940f9a0926a03f --- .../gcc.target/aarch64/aapcs64/aapcs64.exp | 10 +++++ .../gcc.target/aarch64/aapcs64/rec_align-5.c | 44 ++++++++++++++++++++ .../gcc.target/aarch64/aapcs64/rec_align-6.c | 45 +++++++++++++++++++++ .../gcc.target/aarch64/aapcs64/rec_align-7.c | 47 ++++++++++++++++++++++ .../gcc.target/aarch64/aapcs64/rec_align-8.c | 37 +++++++++++++++++ .../gcc.target/aarch64/aapcs64/rec_align-9.c | 41 +++++++++++++++++++ .../gcc.target/aarch64/aapcs64/rec_align_vaarg-1.c | 38 +++++++++++++++++ .../gcc.target/aarch64/aapcs64/rec_align_vaarg-2.c | 28 +++++++++++++ .../gcc.target/aarch64/aapcs64/test_align-5.c | 35 ++++++++++++++++ .../gcc.target/aarch64/aapcs64/test_align-6.c | 36 +++++++++++++++++ .../gcc.target/aarch64/aapcs64/test_align-7.c | 38 +++++++++++++++++ .../gcc.target/aarch64/aapcs64/test_align-8.c | 33 +++++++++++++++ .../gcc.target/aarch64/aapcs64/test_align-9.c | 47 ++++++++++++++++++++++ 13 files changed, 479 insertions(+) create mode 100644 gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align-5.c create mode 100644 gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align-6.c create mode 100644 gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align-7.c create mode 100644 gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align-8.c create mode 100644 gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align-9.c create mode 100644 gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align_vaarg-1.c create mode 100644 gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align_vaarg-2.c create mode 100644 gcc/testsuite/gcc.target/aarch64/aapcs64/test_align-5.c create mode 100644 gcc/testsuite/gcc.target/aarch64/aapcs64/test_align-6.c create mode 100644 gcc/testsuite/gcc.target/aarch64/aapcs64/test_align-7.c create mode 100644 gcc/testsuite/gcc.target/aarch64/aapcs64/test_align-8.c create mode 100644 gcc/testsuite/gcc.target/aarch64/aapcs64/test_align-9.c diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/aapcs64.exp b/gcc/testsuite/gcc.target/aarch64/aapcs64/aapcs64.exp index ad92994..9998d0b 100644 --- a/gcc/testsuite/gcc.target/aarch64/aapcs64/aapcs64.exp +++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/aapcs64.exp @@ -38,6 +38,16 @@ foreach src [lsort [glob -nocomplain $srcdir/$subdir/test_*.c]] { } } +# Test parameter receiving. +set additional_flags_for_rec $additional_flags +append additional_flags_for_rec " -fno-inline" +foreach src [lsort [glob -nocomplain $srcdir/$subdir/rec_*.c]] { + if {[runtest_file_p $runtests $src]} { + c-torture-execute [list $src] \ + $additional_flags_for_rec + } +} + # Test unnamed argument retrieval via the va_arg macro. foreach src [lsort [glob -nocomplain $srcdir/$subdir/va_arg-*.c]] { if {[runtest_file_p $runtests $src]} { diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align-5.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align-5.c new file mode 100644 index 0000000..1b42c92 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align-5.c @@ -0,0 +1,44 @@ +/* Test AAPCS layout (alignment) for callee. */ + +/* { dg-do run { target aarch64*-*-* } } */ + +extern void abort (void); + +typedef __attribute__ ((__aligned__ (8))) int alignedint; + +alignedint a = 11; +alignedint b = 13; +alignedint c = 17; +alignedint d = 19; +alignedint e = 23; +alignedint f = 29; +alignedint g = 31; +alignedint h = 37; +alignedint i = 41; +alignedint j = 43; + +void +test_passing_many_alignedint (alignedint x0, alignedint x1, alignedint x2, + alignedint x3, alignedint x4, alignedint x5, + alignedint x6, alignedint x7, alignedint stack, + alignedint stack8) +{ + if (x0 != a + || x1 != b + || x2 != c + || x3 != d + || x4 != e + || x5 != f + || x6 != g + || x7 != h + || stack != i + || stack8 !=j) + abort (); +} + +int +main (int argc, char **argv) +{ + test_passing_many_alignedint (a, b, c, d, e, f, g, h, i, j); + return 0; +} diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align-6.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align-6.c new file mode 100644 index 0000000..a8d8b1b --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align-6.c @@ -0,0 +1,45 @@ +/* Test AAPCS layout (alignment) for callee. */ + +/* { dg-do run { target aarch64*-*-* } } */ + +extern int memcmp (const void *s1, const void *s2, __SIZE_TYPE__ n); +extern void abort (void); + +/* The underlying struct here has alignment 8. */ +typedef struct __attribute__ ((__aligned__ (16))) + { + long x; + long y; + } overaligned; + +overaligned a = { 2, 3 }; +overaligned b = { 5, 8 }; +overaligned c = { 13, 21 }; + +void +test_passing_overaligned_struct (int x0, overaligned x1, int x3, int x4, + overaligned x5, int x7, int stack, + overaligned stack8) +{ + if (x0 != 7 || x3 != 9 || x4 != 11 || x7 != 15 || stack != 10) + abort (); + if (memcmp ((void *) &x1, (void *)&a, sizeof (overaligned))) + abort (); + if (memcmp ((void *) &x5, (void *)&b, sizeof (overaligned))) + abort (); + if (memcmp ((void *)&stack8, (void *)&c, sizeof (overaligned))) + abort (); + long addr = ((long) &stack8) & 15; + if (addr != 0) + { + __builtin_printf ("Alignment was %d\n", addr); + abort (); + } +} + +int +main (int argc, char **argv) +{ + test_passing_overaligned_struct (7, a, 9, 11, b, 15, 10, c); + return 0; +} diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align-7.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align-7.c new file mode 100644 index 0000000..61e3c11 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align-7.c @@ -0,0 +1,47 @@ +/* Test AAPCS layout (alignment) for callee. */ + +/* { dg-do run { target aarch64*-*-* } } */ + +extern int memcmp (const void *s1, const void *s2, __SIZE_TYPE__ n); +extern void abort (void); + +struct s + { + long x; + long y; + }; + +/* This still has size 16, so is still passed by value. */ +typedef __attribute__ ((__aligned__ (32))) struct s overaligned; + +/* A few structs, at 32-byte-aligned memory locations. */ +overaligned a = { 2, 3 }; +overaligned b = { 5, 8 }; +overaligned c = { 13, 21 }; + +void +test_pass_by_value (int x0, overaligned x1, int x3, int x4, overaligned x5, + int x7, int stack, overaligned stack8) +{ + if (x0 != 7 || x3 != 9 || x4 != 11 || x7 != 15 || stack != 10) + abort (); + if (memcmp ((void *) &x1, (void *)&a, sizeof (overaligned))) + abort (); + if (memcmp ((void *) &x5, (void *)&b, sizeof (overaligned))) + abort (); + if (memcmp ((void *)&stack8, (void *)&c, sizeof (overaligned))) + abort (); + long addr = ((long) &stack8) & 15; + if (addr != 0) + { + __builtin_printf ("Alignment was %d\n", addr); + abort (); + } +} + +int +main (int argc, char **argv) +{ + test_pass_by_value (7, a, 9, 11, b, 15, 10, c); + return 0; +} diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align-8.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align-8.c new file mode 100644 index 0000000..c935180 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align-8.c @@ -0,0 +1,37 @@ +/* Test AAPCS layout (alignment) for callee. */ + +/* { dg-do run { target aarch64*-*-* } } */ + +extern int memcmp (const void *s1, const void *s2, __SIZE_TYPE__ n); +extern void abort (void); + +/* The alignment also gives this size 32, so will be passed by reference. */ +typedef struct __attribute__ ((__aligned__ (32))) + { + long x; + long y; + } overaligned; + +overaligned a = { 2, 3 }; + +void +test_pass_by_ref (int x0, overaligned x1, int x2) +{ + if (x0 != 7 || x2 != 9) + abort (); + if (memcmp ((void *) &x1, (void *)&a, sizeof (overaligned))) + abort (); + long addr = ((long) &x1) & 31; + if (addr != 0) + { + __builtin_printf ("Alignment was %d\n", addr); + abort (); + } +} + +int +main (int argc, char **argv) +{ + test_pass_by_ref (7, a, 9); + return 0; +} diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align-9.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align-9.c new file mode 100644 index 0000000..81139f5 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align-9.c @@ -0,0 +1,41 @@ +/* Test AAPCS layout (alignment) for callee. */ + +/* { dg-do run { target aarch64*-*-* } } */ + +extern int memcmp (const void *s1, const void *s2, __SIZE_TYPE__ n); +extern void abort (void); + +struct s + { + /* This forces the alignment and size of the struct to 16. */ + __attribute__ ((__aligned__ (16))) long x; + int y; + /* 4 bytes padding. */ + }; + +typedef struct s __attribute__ ((__aligned__ (8))) underaligned; + +underaligned a = { 1, 4 }; +underaligned b = { 9, 16 }; +underaligned c = { 25, 36 }; + +void +test_underaligned_struct (int x0, underaligned x2, int x4, underaligned x6, + int stack, underaligned stack16) +{ + if (x0 != 3 || x4 != 5 || stack != 7) + abort (); + if (memcmp ((void *) &x2, (void *)&a, sizeof (underaligned))) + abort (); + if (memcmp ((void *)&x6, (void *)&b, sizeof (underaligned))) + abort (); + if (memcmp ((void *)&stack16, (void *)&c, sizeof (underaligned))) + abort (); +} + +int +main (int argc, char **argv) +{ + test_underaligned_struct (3, a, 5, b, 7, c); + return 0; +} diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align_vaarg-1.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align_vaarg-1.c new file mode 100644 index 0000000..109ddc2 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align_vaarg-1.c @@ -0,0 +1,38 @@ +/* Test AAPCS layout (alignment of varargs) for callee. */ + +/* { dg-do run { target aarch64*-*-* } } */ + +#include + +extern void abort (void); + +typedef __attribute__ ((__aligned__ (16))) long alignedlong; + +void +test_pass_overaligned_long_vaargs (long l, ...) +{ + va_list va; + va_start (va, l); + /* Arguments should be passed in the same registers as if they were ints. */ + while (l-- > 0) + if (va_arg (va, long) != l) + abort (); + va_end (va); +} + +int +main (int argc, char **argv) +{ + alignedlong a = 9; + alignedlong b = 8; + alignedlong c = 7; + alignedlong d = 6; + alignedlong e = 5; + alignedlong f = 4; + alignedlong g = 3; + alignedlong h = 2; + alignedlong i = 1; + alignedlong j = 0; + test_pass_overaligned_long_vaargs (a, b, c, d, e, f, g, h, i, j); + return 0; +} diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align_vaarg-2.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align_vaarg-2.c new file mode 100644 index 0000000..dc4eb2f --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align_vaarg-2.c @@ -0,0 +1,28 @@ +/* Test AAPCS layout (alignment of varargs) for callee. */ + +/* { dg-do run { target aarch64*-*-* } } */ + +#include + +extern void abort (void); + +typedef __attribute__ ((__aligned__ (16))) int alignedint; + +void +test_pass_overaligned_int_vaargs (int i, ...) +{ + va_list va; + va_start (va, i); + /* alignedint should be pulled out of regs/stack just like an int. */ + while (i-- > 0) + if (va_arg (va, alignedint) != i) + abort (); + va_end (va); +} + +int +main (int argc, char **argv) +{ + test_pass_overaligned_int_vaargs (9, 8, 7, 6, 5, 4, 3, 2, 1, 0); + return 0; +} diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/test_align-5.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_align-5.c new file mode 100644 index 0000000..ac5673e --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_align-5.c @@ -0,0 +1,35 @@ +/* Test AAPCS layout (alignment). */ + +/* { dg-do run { target aarch64*-*-* } } */ + +#ifndef IN_FRAMEWORK +#define TESTFILE "test_align-5.c" + +typedef __attribute__ ((__aligned__ (16))) long alignedint; + +alignedint a = 11; +alignedint b = 13; +alignedint c = 17; +alignedint d = 19; +alignedint e = 23; +alignedint f = 29; +alignedint g = 31; +alignedint h = 37; +alignedint i = 41; +alignedint j = 43; + +#include "abitest.h" +#else + ARG (alignedint, a, X0) + /* Attribute suggests R2, but we should use only natural alignment: */ + ARG (alignedint, b, X1) + ARG (alignedint, c, X2) + ARG (alignedint, d, X3) + ARG (alignedint, e, X4) + ARG (alignedint, f, X5) + ARG (alignedint, g, X6) + ARG (alignedint, h, X7) + ARG (alignedint, i, STACK) + /* Attribute would suggest STACK + 16 but should be ignored: */ + LAST_ARG (alignedint, j, STACK + 8) +#endif diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/test_align-6.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_align-6.c new file mode 100644 index 0000000..20cbd94 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_align-6.c @@ -0,0 +1,36 @@ +/* Test AAPCS layout (alignment). */ + +/* { dg-do run { target aarch64*-*-* } } */ + +#ifndef IN_FRAMEWORK +#define TESTFILE "test_align-6.c" + +/* The underlying struct here has alignment 8. */ +typedef struct __attribute__ ((__aligned__ (16))) + { + long x; + long y; + } overaligned; + +/* A couple of instances, at 16-byte-aligned memory locations. */ +overaligned a = { 2, 3 }; +overaligned b = { 5, 8 }; +overaligned c = { 13, 21 }; + +#include "abitest.h" +#else + ARG (int, 7, W0) + /* Natural alignment should be 8. */ + ARG (overaligned, a, X1) + ARG (int, 9, W3) + ARG (int, 11, W4) + ARG (overaligned, b, X5) + ARG (int, 15, W7) +#ifndef __AAPCS64_BIG_ENDIAN__ + ARG (int, 10, STACK) +#else + ARG (int, 10, STACK + 4) +#endif + /* Natural alignment should be 8. */ + LAST_ARG (overaligned, c, STACK + 8) +#endif diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/test_align-7.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_align-7.c new file mode 100644 index 0000000..6af422f --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_align-7.c @@ -0,0 +1,38 @@ +/* Test AAPCS layout (alignment). */ + +/* { dg-do run { target aarch64*-*-* } } */ + +#ifndef IN_FRAMEWORK +#define TESTFILE "test_align-7.c" + +struct s + { + long x; + long y; + }; + +/* This still has size 16, so is still passed by value. */ +typedef __attribute__ ((__aligned__ (32))) struct s overaligned; + +/* A few structs, at 32-byte-aligned memory locations. */ +overaligned a = { 2, 3 }; +overaligned b = { 5, 8 }; +overaligned c = { 13, 21 }; + +#include "abitest.h" +#else + ARG (int, 7, W0) + /* Alignment should be 8. */ + ARG (overaligned, a, X1) + ARG (int, 9, W3) + ARG (int, 11, W4) + ARG (overaligned, b, X5) + ARG (int, 15, W7) +#ifndef __AAPCS64_BIG_ENDIAN__ + ARG (int, 10, STACK) +#else + ARG (int, 10, STACK + 4) +#endif + /* Natural alignment should be 8. */ + LAST_ARG (overaligned, c, STACK + 8) +#endif diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/test_align-8.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_align-8.c new file mode 100644 index 0000000..ad4dfe4 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_align-8.c @@ -0,0 +1,33 @@ +/* Test AAPCS layout (alignment). */ + +/* { dg-do run { target aarch64*-*-* } } */ + +#ifndef IN_FRAMEWORK +#define TESTFILE "test_align-8.c" + +/* The alignment also gives this size 32, so will be passed by reference. */ +typedef struct __attribute__ ((__aligned__ (32))) + { + long x; + long y; + } overaligned; + +#define EXPECTED_STRUCT_SIZE 32 +extern void link_failure (void); +int +foo () +{ + /* Optimization gets rid of this before linking. */ + if (sizeof (overaligned) != EXPECTED_STRUCT_SIZE) + link_failure (); +} + +overaligned a = { 2, 3 }; + +#include "abitest.h" +#else + ARG (int, 7, W0) + /* Alignment should be 8. */ + PTR (overaligned, a, X1) + LAST_ARG (int, 9, W2) +#endif diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/test_align-9.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_align-9.c new file mode 100644 index 0000000..0f5fa35 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_align-9.c @@ -0,0 +1,47 @@ +/* Test AAPCS layout (alignment). */ + +/* { dg-do run { target aarch64*-*-* } } */ + +#ifndef IN_FRAMEWORK +#define TESTFILE "test_align-9.c" + +struct s + { + /* This forces the alignment and size of the struct to 16. */ + __attribute__ ((__aligned__ (16))) long x; + int y; + /* 4 bytes padding. */ + }; + +typedef struct s __attribute__ ((__aligned__ (8))) underaligned; + +#define EXPECTED_STRUCT_SIZE 16 +extern void link_failure (void); +int +foo () +{ + /* Optimization gets rid of this before linking. */ + if (sizeof (struct s) != EXPECTED_STRUCT_SIZE) + link_failure (); +} + +underaligned a = { 1, 4 }; +underaligned b = { 9, 16 }; +underaligned c = { 25, 36 }; + +#include "abitest.h" +#else + ARG (int, 3, W0) + /* Object alignment is 16, so skip X1. */ + ARG (underaligned, a, X2) + ARG (int, 5, W4) + /* Object alignment is 16, so skip X5. */ + ARG (underaligned, b, X6) +#ifndef __AAPCS64_BIG_ENDIAN__ + ARG (int, 7, STACK) +#else + ARG (int, 7, STACK + 4) +#endif + /* Natural alignment should be 16. */ + LAST_ARG (underaligned, c, STACK + 16) +#endif -- 2.7.4 From 8f0da1d02a4956801ccd1d0df529ca68d821d8e9 Mon Sep 17 00:00:00 2001 From: Sangmin Seo Date: Thu, 29 Jun 2017 16:56:39 +0900 Subject: [PATCH 07/16] Do not emit the -Wpsabi note for PR target/77728 Since PR target/77728 issue did not exist in Tizen/Linaro GCC 4.9.2 and has been resolved with the upstream patches, it does not make sense to print the -Wpsabi note, which is "parameter passing for argument of type ... changed in GCC 7.1." This patch removes the -Wpsabi note generated by the commit 6da83d4adc857ba1c4370b2b8f32825d5cb13ebe and dg-message comments from the test code. gcc/config/ * arm/arm.c (aapcs_layout_arg): Remove code emitting -Wpsabi note. (arm_function_arg): Likewise. (arm_function_arg_boundary): Likewise. (arm_setup_incoming_varargs): Likewise. gcc/testsuite/ * g++.dg/abi/pr77728-1.C: Remove dg-message comments. Change-Id: I5432536052bf9d534e21157ddfd2ac57d25da59f Signed-off-by: Sangmin Seo --- gcc/config/arm/arm.c | 23 +++-------------------- gcc/testsuite/g++.dg/abi/pr77728-1.C | 14 ++++---------- 2 files changed, 7 insertions(+), 30 deletions(-) diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 5ab94d9..f48fe56 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -6208,15 +6208,7 @@ aapcs_layout_arg (CUMULATIVE_ARGS *pcum, machine_mode mode, if (ncrn & 1) { int res = arm_needs_doubleword_align (mode, type); - /* Only warn during RTL expansion of call stmts, otherwise we would - warn e.g. during gimplification even on functions that will be - always inlined, and we'd warn multiple times. Don't warn when - called in expand_function_start either, as we warn instead in - arm_function_arg_boundary in that case. */ - if (res < 0 && warn_psabi && currently_expanding_gimple_stmt) - inform (input_location, "parameter passing for argument of type " - "%qT changed in GCC 7.1", type); - else if (res > 0) + if (res > 0) ncrn++; } @@ -6416,10 +6408,7 @@ arm_function_arg (cumulative_args_t pcum_v, machine_mode mode, if ((pcum->nregs & 1) && ARM_DOUBLEWORD_ALIGN) { int res = arm_needs_doubleword_align (mode, type); - if (res < 0 && warn_psabi) - inform (input_location, "parameter passing for argument of type " - "%qT changed in GCC 7.1", type); - else if (res > 0) + if (res > 0) pcum->nregs++; } @@ -6444,9 +6433,6 @@ arm_function_arg_boundary (machine_mode mode, const_tree type) return PARM_BOUNDARY; int res = arm_needs_doubleword_align (mode, type); - if (res < 0 && warn_psabi) - inform (input_location, "parameter passing for argument of type %qT " - "changed in GCC 7.1", type); return res > 0 ? DOUBLEWORD_ALIGNMENT : PARM_BOUNDARY; } @@ -26342,10 +26328,7 @@ arm_setup_incoming_varargs (cumulative_args_t pcum_v, if (nregs & 1) { int res = arm_needs_doubleword_align (mode, type); - if (res < 0 && warn_psabi) - inform (input_location, "parameter passing for argument of " - "type %qT changed in GCC 7.1", type); - else if (res > 0) + if (res > 0) nregs++; } } diff --git a/gcc/testsuite/g++.dg/abi/pr77728-1.C b/gcc/testsuite/g++.dg/abi/pr77728-1.C index 05f08c9..15ccbfb 100644 --- a/gcc/testsuite/g++.dg/abi/pr77728-1.C +++ b/gcc/testsuite/g++.dg/abi/pr77728-1.C @@ -30,7 +30,7 @@ struct K : public D { typedef A T; int i, j; }; struct L { static double h; int i, j; }; int -fn1 (int a, B<0> b) // { dg-message "note: parameter passing for argument of type \[^\n\r]* changed in GCC 7\.1" } +fn1 (int a, B<0> b) { return a + b.i; } @@ -42,14 +42,13 @@ fn2 (int a, B<1> b) } int -fn3 (int a, L b) // { dg-message "note: parameter passing for argument of type \[^\n\r]* changed in GCC 7\.1" } +fn3 (int a, L b) { return a + b.i; } int fn4 (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m, B<0> n, ...) -// { dg-message "note: parameter passing for argument of type \[^\n\r]* changed in GCC 7\.1" "" { target *-*-* } .-1 } { va_list ap; va_start (ap, n); @@ -110,7 +109,6 @@ fn9 (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k int fn10 (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m, J n, ...) -// { dg-message "note: parameter passing for argument of type \[^\n\r]* changed in GCC 7\.1" "" { target *-*-* } .-1 } { va_list ap; va_start (ap, n); @@ -121,7 +119,6 @@ fn10 (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int int fn11 (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m, K<0> n, ...) -// { dg-message "note: parameter passing for argument of type \[^\n\r]* changed in GCC 7\.1" "" { target *-*-* } .-1 } { va_list ap; va_start (ap, n); @@ -153,19 +150,16 @@ test () static J j; static K<0> k0; static K<2> k2; - fn1 (1, b0); // { dg-message "note: parameter passing for argument of type \[^\n\r]* changed in GCC 7\.1" } + fn1 (1, b0); fn2 (1, b1); - fn3 (1, l); // { dg-message "note: parameter passing for argument of type \[^\n\r]* changed in GCC 7\.1" } + fn3 (1, l); fn4 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, b0, 1, 2, 3, 4); - // { dg-message "note: parameter passing for argument of type \[^\n\r]* changed in GCC 7\.1" "" { target *-*-* } .-1 } fn5 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, b1, 1, 2, 3, 4); fn6 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, c, 1, 2, 3, 4); fn7 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, e, 1, 2, 3, 4); fn8 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, h, 1, 2, 3, 4); fn9 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, i, 1, 2, 3, 4); fn10 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, j, 1, 2, 3, 4); - // { dg-message "note: parameter passing for argument of type \[^\n\r]* changed in GCC 7\.1" "" { target *-*-* } .-1 } fn11 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, k0, 1, 2, 3, 4); - // { dg-message "note: parameter passing for argument of type \[^\n\r]* changed in GCC 7\.1" "" { target *-*-* } .-1 } fn12 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, k2, 1, 2, 3, 4); } -- 2.7.4 From 84bd4b431e26d7a03cb4318423fed860a9a9dfe2 Mon Sep 17 00:00:00 2001 From: Slava Barinov Date: Thu, 13 Jul 2017 13:35:02 +0300 Subject: [PATCH 08/16] packaging: Add %gcc_force_options and %gcc_unforce_options macros The macros can be used in certain .spec files to switch off sanitization of parts or modules without hard-coding sanitizer flags into packages. Change-Id: I1643a3bdd64a3d48855f02622feb064d482e3655 Signed-off-by: Slava Barinov Signed-off-by: Sangmin Seo --- packaging/gcc-aarch64.spec | 48 ++++++++++++++++++++++++++++++++++++---------- packaging/gcc-armv7l.spec | 48 ++++++++++++++++++++++++++++++++++++---------- packaging/linaro-gcc.spec | 48 ++++++++++++++++++++++++++++++++++++---------- 3 files changed, 114 insertions(+), 30 deletions(-) diff --git a/packaging/gcc-aarch64.spec b/packaging/gcc-aarch64.spec index 40d1ae6..89261f6 100644 --- a/packaging/gcc-aarch64.spec +++ b/packaging/gcc-aarch64.spec @@ -54,6 +54,14 @@ %define libdir %{!?cross:%{_libdir}}%{?cross:%{_prefix}/lib%{?aarch64:64}} %define libsubdir %{libdir}/gcc/%{target_arch}/%{version} +%define asan_force_options -fsanitize-recover=address -fsanitize=address -fno-omit-frame-pointer -Wp,-U_FORTIFY_SOURCE +%define ubsan_force_options -fsanitize=undefined,bounds-strict,float-divide-by-zero,float-cast-overflow +%define lsan_force_options -fsanitize=leak -fno-omit-frame-pointer -Wp,-U_FORTIFY_SOURCE + +%define asan_runtime_options halt_on_error=false:start_deactivated=true:print_cmdline=true:quarantine_size_mb=1:detect_leaks=0:log_path=/tmp/asan.log:log_exe_name=1 +%define ubsan_runtime_options print_cmdline=true:log_path=/tmp/ubsan.log +%define lsan_runtime_options print_cmdline=true:detect_leaks=1:log_path=/tmp/lsan.log:log_exe_name=1:fast_unwind_on_malloc=false:malloc_context_size=5:suppressions=/lsan.supp:print_suppressions=false + Name: gcc%{?cross:-%{cross}} # With generated files in src we could drop the following BuildRequires: bison @@ -649,14 +657,17 @@ Scripts for ASan instrumentation # Change mode to allow all users to run gcc-force/unforce-options chmod a+w /usr/bin [ -d /emul/ ] && chmod a+w /emul/usr/bin/ && chmod a+w /emul/home/abuild/rpmbuild/BUILD/gcc-%{version}/obj/gcc/ -/usr/bin/gcc-force-options -fsanitize-recover=address -fsanitize=address -fno-common -fno-omit-frame-pointer -U_FORTIFY_SOURCE -# Add restore_fcommon macro +/usr/bin/gcc-force-options %asan_force_options -fno-common +# Add ASan-related macros cat >> /usr/lib/rpm/tizen_macros << EOF -%restore_fcommon \\ - /usr/bin/gcc-unforce-options \\ - /usr/bin/gcc-force-options -fsanitize-recover=address -fsanitize=address -fcommon -fno-omit-frame-pointer -U_FORTIFY_SOURCE - +%%asan_force_options %{asan_force_options} +%%gcc_unforce_options /usr/bin/gcc-unforce-options +%%gcc_force_options /usr/bin/gcc-force-options +%%gcc_force_default_options %%gcc_force_options %%asan_force_options -fno-common +%%restore_fcommon \\ + %%gcc_unforce_options \\ + %%gcc_force_options %%asan_force_options -fcommon EOF %preun -n asan-force-options @@ -678,7 +689,15 @@ Scripts for UBSan instrumentation # Change mode to allow all users to run gcc-force/unforce-options chmod a+w /usr/bin [ -d /emul/ ] && chmod a+w /emul/usr/bin/ && chmod a+w /emul/home/abuild/rpmbuild/BUILD/gcc-%{version}/obj/gcc/ -/usr/bin/gcc-force-options -fsanitize=undefined,bounds-strict,float-divide-by-zero,float-cast-overflow +/usr/bin/gcc-force-options %ubsan_force_options +# Add UBSan-related macros +cat >> /usr/lib/rpm/tizen_macros << EOF + +%%ubsan_force_options %{ubsan_force_options} +%%gcc_unforce_options /usr/bin/gcc-unforce-options +%%gcc_force_options /usr/bin/gcc-force-options +%%gcc_force_default_options %%gcc_force_options %%ubsan_force_options +EOF %preun -n ubsan-force-options # Restore read-only mode @@ -711,7 +730,15 @@ Scripts for LSan instrumentation # Change mode to allow all users to run gcc-force/unforce-options chmod a+w /usr/bin [ -d /emul/ ] && chmod a+w /emul/usr/bin/ && chmod a+w /emul/home/abuild/rpmbuild/BUILD/gcc-%{version}/obj/gcc/ -/usr/bin/gcc-force-options -fsanitize=leak -fno-omit-frame-pointer -U_FORTIFY_SOURCE +/usr/bin/gcc-force-options %lsan_force_options +# Add LSan-related macros +cat >> /usr/lib/rpm/tizen_macros << EOF + +%%lsan_force_options %{lsan_force_options} +%%gcc_unforce_options /usr/bin/gcc-unforce-options +%%gcc_force_options /usr/bin/gcc-force-options +%%gcc_force_default_options %%gcc_force_options %%lsan_force_options +EOF %preun -n lsan-force-options # Restore read-only mode @@ -754,6 +781,7 @@ LSan runtime environment echo "%{libdir}/liblsan.so" > /etc/ld.so.preload [ -f /etc/ld.so.preload.orig ] && cat /etc/ld.so.preload.orig >> /etc/ld.so.preload [ -f /etc/ld.so.preload.orig ] && rm -f /etc/ld.so.preload.orig +echo "%{lsan_runtime_options}" > /LSAN_OPTIONS chsmack -a "_" /etc/ld.so.preload /LSAN_OPTIONS /lsan.supp %preun -n lsan-runtime-env @@ -785,7 +813,7 @@ Asan runtime environment echo "%{libdir}/libasan.so" > /etc/ld.so.preload [ -f /etc/ld.so.preload.orig ] && cat /etc/ld.so.preload.orig >> /etc/ld.so.preload [ -f /etc/ld.so.preload.orig ] && rm -f /etc/ld.so.preload.orig -echo "halt_on_error=false:start_deactivated=true:print_cmdline=true:quarantine_size_mb=1:detect_leaks=0:log_path=/tmp/asan.log:log_exe_name=1" > /ASAN_OPTIONS +echo "%{asan_runtime_options}" > /ASAN_OPTIONS chsmack -a "_" /etc/ld.so.preload /ASAN_OPTIONS %preun -n asan-runtime-env @@ -801,7 +829,7 @@ Requires: libubsan UBSan runtime environment %post -n ubsan-runtime-env -echo "print_cmdline=true:log_path=/tmp/ubsan.log" > /UBSAN_OPTIONS +echo "%{ubsan_runtime_options}" > /UBSAN_OPTIONS %package plugin-devel Summary: GNU GCC Plugin development files diff --git a/packaging/gcc-armv7l.spec b/packaging/gcc-armv7l.spec index f3ad3bd..9c163e1 100644 --- a/packaging/gcc-armv7l.spec +++ b/packaging/gcc-armv7l.spec @@ -54,6 +54,14 @@ %define libdir %{!?cross:%{_libdir}}%{?cross:%{_prefix}/lib%{?aarch64:64}} %define libsubdir %{libdir}/gcc/%{target_arch}/%{version} +%define asan_force_options -fsanitize-recover=address -fsanitize=address -fno-omit-frame-pointer -Wp,-U_FORTIFY_SOURCE +%define ubsan_force_options -fsanitize=undefined,bounds-strict,float-divide-by-zero,float-cast-overflow +%define lsan_force_options -fsanitize=leak -fno-omit-frame-pointer -Wp,-U_FORTIFY_SOURCE + +%define asan_runtime_options halt_on_error=false:start_deactivated=true:print_cmdline=true:quarantine_size_mb=1:detect_leaks=0:log_path=/tmp/asan.log:log_exe_name=1 +%define ubsan_runtime_options print_cmdline=true:log_path=/tmp/ubsan.log +%define lsan_runtime_options print_cmdline=true:detect_leaks=1:log_path=/tmp/lsan.log:log_exe_name=1:fast_unwind_on_malloc=false:malloc_context_size=5:suppressions=/lsan.supp:print_suppressions=false + Name: gcc%{?cross:-%{cross}} # With generated files in src we could drop the following BuildRequires: bison @@ -649,14 +657,17 @@ Scripts for ASan instrumentation # Change mode to allow all users to run gcc-force/unforce-options chmod a+w /usr/bin [ -d /emul/ ] && chmod a+w /emul/usr/bin/ && chmod a+w /emul/home/abuild/rpmbuild/BUILD/gcc-%{version}/obj/gcc/ -/usr/bin/gcc-force-options -fsanitize-recover=address -fsanitize=address -fno-common -fno-omit-frame-pointer -U_FORTIFY_SOURCE -# Add restore_fcommon macro +/usr/bin/gcc-force-options %asan_force_options -fno-common +# Add ASan-related macros cat >> /usr/lib/rpm/tizen_macros << EOF -%restore_fcommon \\ - /usr/bin/gcc-unforce-options \\ - /usr/bin/gcc-force-options -fsanitize-recover=address -fsanitize=address -fcommon -fno-omit-frame-pointer -U_FORTIFY_SOURCE - +%%asan_force_options %{asan_force_options} +%%gcc_unforce_options /usr/bin/gcc-unforce-options +%%gcc_force_options /usr/bin/gcc-force-options +%%gcc_force_default_options %%gcc_force_options %%asan_force_options -fno-common +%%restore_fcommon \\ + %%gcc_unforce_options \\ + %%gcc_force_options %%asan_force_options -fcommon EOF %preun -n asan-force-options @@ -678,7 +689,15 @@ Scripts for UBSan instrumentation # Change mode to allow all users to run gcc-force/unforce-options chmod a+w /usr/bin [ -d /emul/ ] && chmod a+w /emul/usr/bin/ && chmod a+w /emul/home/abuild/rpmbuild/BUILD/gcc-%{version}/obj/gcc/ -/usr/bin/gcc-force-options -fsanitize=undefined,bounds-strict,float-divide-by-zero,float-cast-overflow +/usr/bin/gcc-force-options %ubsan_force_options +# Add UBSan-related macros +cat >> /usr/lib/rpm/tizen_macros << EOF + +%%ubsan_force_options %{ubsan_force_options} +%%gcc_unforce_options /usr/bin/gcc-unforce-options +%%gcc_force_options /usr/bin/gcc-force-options +%%gcc_force_default_options %%gcc_force_options %%ubsan_force_options +EOF %preun -n ubsan-force-options # Restore read-only mode @@ -711,7 +730,15 @@ Scripts for LSan instrumentation # Change mode to allow all users to run gcc-force/unforce-options chmod a+w /usr/bin [ -d /emul/ ] && chmod a+w /emul/usr/bin/ && chmod a+w /emul/home/abuild/rpmbuild/BUILD/gcc-%{version}/obj/gcc/ -/usr/bin/gcc-force-options -fsanitize=leak -fno-omit-frame-pointer -U_FORTIFY_SOURCE +/usr/bin/gcc-force-options %lsan_force_options +# Add LSan-related macros +cat >> /usr/lib/rpm/tizen_macros << EOF + +%%lsan_force_options %{lsan_force_options} +%%gcc_unforce_options /usr/bin/gcc-unforce-options +%%gcc_force_options /usr/bin/gcc-force-options +%%gcc_force_default_options %%gcc_force_options %%lsan_force_options +EOF %preun -n lsan-force-options # Restore read-only mode @@ -754,6 +781,7 @@ LSan runtime environment echo "%{libdir}/liblsan.so" > /etc/ld.so.preload [ -f /etc/ld.so.preload.orig ] && cat /etc/ld.so.preload.orig >> /etc/ld.so.preload [ -f /etc/ld.so.preload.orig ] && rm -f /etc/ld.so.preload.orig +echo "%{lsan_runtime_options}" > /LSAN_OPTIONS chsmack -a "_" /etc/ld.so.preload /LSAN_OPTIONS /lsan.supp %preun -n lsan-runtime-env @@ -785,7 +813,7 @@ Asan runtime environment echo "%{libdir}/libasan.so" > /etc/ld.so.preload [ -f /etc/ld.so.preload.orig ] && cat /etc/ld.so.preload.orig >> /etc/ld.so.preload [ -f /etc/ld.so.preload.orig ] && rm -f /etc/ld.so.preload.orig -echo "halt_on_error=false:start_deactivated=true:print_cmdline=true:quarantine_size_mb=1:detect_leaks=0:log_path=/tmp/asan.log:log_exe_name=1" > /ASAN_OPTIONS +echo "%{asan_runtime_options}" > /ASAN_OPTIONS chsmack -a "_" /etc/ld.so.preload /ASAN_OPTIONS %preun -n asan-runtime-env @@ -801,7 +829,7 @@ Requires: libubsan UBSan runtime environment %post -n ubsan-runtime-env -echo "print_cmdline=true:log_path=/tmp/ubsan.log" > /UBSAN_OPTIONS +echo "%{ubsan_runtime_options}" > /UBSAN_OPTIONS %package plugin-devel Summary: GNU GCC Plugin development files diff --git a/packaging/linaro-gcc.spec b/packaging/linaro-gcc.spec index c6460cf..49d2499 100644 --- a/packaging/linaro-gcc.spec +++ b/packaging/linaro-gcc.spec @@ -51,6 +51,14 @@ %define libdir %{!?cross:%{_libdir}}%{?cross:%{_prefix}/lib%{?aarch64:64}} %define libsubdir %{libdir}/gcc/%{target_arch}/%{version} +%define asan_force_options -fsanitize-recover=address -fsanitize=address -fno-omit-frame-pointer -Wp,-U_FORTIFY_SOURCE +%define ubsan_force_options -fsanitize=undefined,bounds-strict,float-divide-by-zero,float-cast-overflow +%define lsan_force_options -fsanitize=leak -fno-omit-frame-pointer -Wp,-U_FORTIFY_SOURCE + +%define asan_runtime_options halt_on_error=false:start_deactivated=true:print_cmdline=true:quarantine_size_mb=1:detect_leaks=0:log_path=/tmp/asan.log:log_exe_name=1 +%define ubsan_runtime_options print_cmdline=true:log_path=/tmp/ubsan.log +%define lsan_runtime_options print_cmdline=true:detect_leaks=1:log_path=/tmp/lsan.log:log_exe_name=1:fast_unwind_on_malloc=false:malloc_context_size=5:suppressions=/lsan.supp:print_suppressions=false + Name: gcc%{?cross:-%{cross}} # With generated files in src we could drop the following BuildRequires: bison @@ -646,14 +654,17 @@ Scripts for ASan instrumentation # Change mode to allow all users to run gcc-force/unforce-options chmod a+w /usr/bin [ -d /emul/ ] && chmod a+w /emul/usr/bin/ && chmod a+w /emul/home/abuild/rpmbuild/BUILD/gcc-%{version}/obj/gcc/ -/usr/bin/gcc-force-options -fsanitize-recover=address -fsanitize=address -fno-common -fno-omit-frame-pointer -U_FORTIFY_SOURCE -# Add restore_fcommon macro +/usr/bin/gcc-force-options %asan_force_options -fno-common +# Add ASan-related macros cat >> /usr/lib/rpm/tizen_macros << EOF -%restore_fcommon \\ - /usr/bin/gcc-unforce-options \\ - /usr/bin/gcc-force-options -fsanitize-recover=address -fsanitize=address -fcommon -fno-omit-frame-pointer -U_FORTIFY_SOURCE - +%%asan_force_options %{asan_force_options} +%%gcc_unforce_options /usr/bin/gcc-unforce-options +%%gcc_force_options /usr/bin/gcc-force-options +%%gcc_force_default_options %%gcc_force_options %%asan_force_options -fno-common +%%restore_fcommon \\ + %%gcc_unforce_options \\ + %%gcc_force_options %%asan_force_options -fcommon EOF %preun -n asan-force-options @@ -675,7 +686,15 @@ Scripts for UBSan instrumentation # Change mode to allow all users to run gcc-force/unforce-options chmod a+w /usr/bin [ -d /emul/ ] && chmod a+w /emul/usr/bin/ && chmod a+w /emul/home/abuild/rpmbuild/BUILD/gcc-%{version}/obj/gcc/ -/usr/bin/gcc-force-options -fsanitize=undefined,bounds-strict,float-divide-by-zero,float-cast-overflow +/usr/bin/gcc-force-options %ubsan_force_options +# Add UBSan-related macros +cat >> /usr/lib/rpm/tizen_macros << EOF + +%%ubsan_force_options %{ubsan_force_options} +%%gcc_unforce_options /usr/bin/gcc-unforce-options +%%gcc_force_options /usr/bin/gcc-force-options +%%gcc_force_default_options %%gcc_force_options %%ubsan_force_options +EOF %preun -n ubsan-force-options # Restore read-only mode @@ -708,7 +727,15 @@ Scripts for LSan instrumentation # Change mode to allow all users to run gcc-force/unforce-options chmod a+w /usr/bin [ -d /emul/ ] && chmod a+w /emul/usr/bin/ && chmod a+w /emul/home/abuild/rpmbuild/BUILD/gcc-%{version}/obj/gcc/ -/usr/bin/gcc-force-options -fsanitize=leak -fno-omit-frame-pointer -U_FORTIFY_SOURCE +/usr/bin/gcc-force-options %lsan_force_options +# Add LSan-related macros +cat >> /usr/lib/rpm/tizen_macros << EOF + +%%lsan_force_options %{lsan_force_options} +%%gcc_unforce_options /usr/bin/gcc-unforce-options +%%gcc_force_options /usr/bin/gcc-force-options +%%gcc_force_default_options %%gcc_force_options %%lsan_force_options +EOF %preun -n lsan-force-options # Restore read-only mode @@ -751,6 +778,7 @@ LSan runtime environment echo "%{libdir}/liblsan.so" > /etc/ld.so.preload [ -f /etc/ld.so.preload.orig ] && cat /etc/ld.so.preload.orig >> /etc/ld.so.preload [ -f /etc/ld.so.preload.orig ] && rm -f /etc/ld.so.preload.orig +echo "%{lsan_runtime_options}" > /LSAN_OPTIONS chsmack -a "_" /etc/ld.so.preload /LSAN_OPTIONS /lsan.supp %preun -n lsan-runtime-env @@ -782,7 +810,7 @@ Asan runtime environment echo "%{libdir}/libasan.so" > /etc/ld.so.preload [ -f /etc/ld.so.preload.orig ] && cat /etc/ld.so.preload.orig >> /etc/ld.so.preload [ -f /etc/ld.so.preload.orig ] && rm -f /etc/ld.so.preload.orig -echo "halt_on_error=false:start_deactivated=true:print_cmdline=true:quarantine_size_mb=1:detect_leaks=0:log_path=/tmp/asan.log:log_exe_name=1" > /ASAN_OPTIONS +echo "%{asan_runtime_options}" > /ASAN_OPTIONS chsmack -a "_" /etc/ld.so.preload /ASAN_OPTIONS %preun -n asan-runtime-env @@ -798,7 +826,7 @@ Requires: libubsan UBSan runtime environment %post -n ubsan-runtime-env -echo "print_cmdline=true:log_path=/tmp/ubsan.log" > /UBSAN_OPTIONS +echo "%{ubsan_runtime_options}" > /UBSAN_OPTIONS %package plugin-devel Summary: GNU GCC Plugin development files -- 2.7.4 From c51983b611f888ce51c6c137b50038a0daee45e9 Mon Sep 17 00:00:00 2001 From: Sangmin Seo Date: Tue, 18 Jul 2017 14:01:23 +0900 Subject: [PATCH 09/16] packaging: create a wrapper for collect2 in gcc-force-options gcc-force-options used to prepend/append all force options to the gcc/g++ wrappers. This approach worked well for most packages but caused some configure scripts to behave differently when linker flags are included in the force options. For example, if g++ is called with -ldl appended, it always goes to the linking phase. As a result, when configure has expanded AC_PROG_CXXCPP macro, variables related to preprocessor are not properly set and actual build ends up using incorrect compile and link flags. Since prepending or appending linker flags to the linker makes more sense than carrying them from the compilation phase, this patch basically divides the force options into compiler flags and linker ones, and inserts them to corresponding wrappers. Consequently, a wrapper for collect2 is created, as we did for gcc and g++, in order to pass the linker flags to the linker. Note that collect2 bridges the compiler and the actual linker, and thus creating a wrapper for collect2 is more portable and succinct than doing so for linkers. Change-Id: I8733bf14c5a2c04bfebe38a339c94e7a738cf17c Signed-off-by: Sangmin Seo --- packaging/gcc-aarch64.spec | 24 ++++++++++---- packaging/gcc-armv7l.spec | 24 ++++++++++---- packaging/gcc-force-options | 73 ++++++++++++++++++++++++++++++++++++++----- packaging/gcc-unforce-options | 2 +- packaging/linaro-gcc.spec | 24 ++++++++++---- 5 files changed, 121 insertions(+), 26 deletions(-) diff --git a/packaging/gcc-aarch64.spec b/packaging/gcc-aarch64.spec index 89261f6..ef0e568 100644 --- a/packaging/gcc-aarch64.spec +++ b/packaging/gcc-aarch64.spec @@ -656,7 +656,9 @@ Scripts for ASan instrumentation %post -n asan-force-options # Change mode to allow all users to run gcc-force/unforce-options chmod a+w /usr/bin -[ -d /emul/ ] && chmod a+w /emul/usr/bin/ && chmod a+w /emul/home/abuild/rpmbuild/BUILD/gcc-%{version}/obj/gcc/ +chmod a+w %{libsubdir} +[ -d /emul/ ] && chmod a+w /emul/usr/bin/ && chmod a+w /emul/home/abuild/rpmbuild/BUILD/gcc-%{version}/obj/gcc/ \ + && find -L /emul/usr/*/gcc -name 'collect2' | xargs dirname | xargs chmod a+w /usr/bin/gcc-force-options %asan_force_options -fno-common # Add ASan-related macros cat >> /usr/lib/rpm/tizen_macros << EOF @@ -673,7 +675,9 @@ EOF %preun -n asan-force-options # Restore read-only mode chmod a-w /usr/bin -[ -d /emul/ ] && chmod a-w /emul/usr/bin/ && chmod a-w /emul/home/abuild/rpmbuild/BUILD/gcc-%{version}/obj/gcc/ +chmod a-w %{libsubdir} +[ -d /emul/ ] && chmod a-w /emul/usr/bin/ && chmod a-w /emul/home/abuild/rpmbuild/BUILD/gcc-%{version}/obj/gcc/ \ + && find -L /emul/usr/*/gcc -name 'collect2' | xargs dirname | xargs chmod a-w /usr/bin/gcc-unforce-options %package -n ubsan-force-options @@ -688,7 +692,9 @@ Scripts for UBSan instrumentation %post -n ubsan-force-options # Change mode to allow all users to run gcc-force/unforce-options chmod a+w /usr/bin -[ -d /emul/ ] && chmod a+w /emul/usr/bin/ && chmod a+w /emul/home/abuild/rpmbuild/BUILD/gcc-%{version}/obj/gcc/ +chmod a+w %{libsubdir} +[ -d /emul/ ] && chmod a+w /emul/usr/bin/ && chmod a+w /emul/home/abuild/rpmbuild/BUILD/gcc-%{version}/obj/gcc/ \ + && find -L /emul/usr/*/gcc -name 'collect2' | xargs dirname | xargs chmod a+w /usr/bin/gcc-force-options %ubsan_force_options # Add UBSan-related macros cat >> /usr/lib/rpm/tizen_macros << EOF @@ -702,7 +708,9 @@ EOF %preun -n ubsan-force-options # Restore read-only mode chmod a-w /usr/bin -[ -d /emul/ ] && chmod a-w /emul/usr/bin/ && chmod a-w /emul/home/abuild/rpmbuild/BUILD/gcc-%{version}/obj/gcc/ +chmod a-w %{libsubdir} +[ -d /emul/ ] && chmod a-w /emul/usr/bin/ && chmod a-w /emul/home/abuild/rpmbuild/BUILD/gcc-%{version}/obj/gcc/ \ + && find -L /emul/usr/*/gcc -name 'collect2' | xargs dirname | xargs chmod a-w /usr/bin/gcc-unforce-options %package -n ubsan-build-env @@ -729,7 +737,9 @@ Scripts for LSan instrumentation %post -n lsan-force-options # Change mode to allow all users to run gcc-force/unforce-options chmod a+w /usr/bin -[ -d /emul/ ] && chmod a+w /emul/usr/bin/ && chmod a+w /emul/home/abuild/rpmbuild/BUILD/gcc-%{version}/obj/gcc/ +chmod a+w %{libsubdir} +[ -d /emul/ ] && chmod a+w /emul/usr/bin/ && chmod a+w /emul/home/abuild/rpmbuild/BUILD/gcc-%{version}/obj/gcc/ \ + && find -L /emul/usr/*/gcc -name 'collect2' | xargs dirname | xargs chmod a+w /usr/bin/gcc-force-options %lsan_force_options # Add LSan-related macros cat >> /usr/lib/rpm/tizen_macros << EOF @@ -743,7 +753,9 @@ EOF %preun -n lsan-force-options # Restore read-only mode chmod a-w /usr/bin -[ -d /emul/ ] && chmod a-w /emul/usr/bin/ && chmod a-w /emul/home/abuild/rpmbuild/BUILD/gcc-%{version}/obj/gcc/ +chmod a-w %{libsubdir} +[ -d /emul/ ] && chmod a-w /emul/usr/bin/ && chmod a-w /emul/home/abuild/rpmbuild/BUILD/gcc-%{version}/obj/gcc/ \ + && find -L /emul/usr/*/gcc -name 'collect2' | xargs dirname | xargs chmod a-w /usr/bin/gcc-unforce-options [ -d /emul/ ] && chmod a-w /emul/usr/bin/ diff --git a/packaging/gcc-armv7l.spec b/packaging/gcc-armv7l.spec index 9c163e1..878d527 100644 --- a/packaging/gcc-armv7l.spec +++ b/packaging/gcc-armv7l.spec @@ -656,7 +656,9 @@ Scripts for ASan instrumentation %post -n asan-force-options # Change mode to allow all users to run gcc-force/unforce-options chmod a+w /usr/bin -[ -d /emul/ ] && chmod a+w /emul/usr/bin/ && chmod a+w /emul/home/abuild/rpmbuild/BUILD/gcc-%{version}/obj/gcc/ +chmod a+w %{libsubdir} +[ -d /emul/ ] && chmod a+w /emul/usr/bin/ && chmod a+w /emul/home/abuild/rpmbuild/BUILD/gcc-%{version}/obj/gcc/ \ + && find -L /emul/usr/*/gcc -name 'collect2' | xargs dirname | xargs chmod a+w /usr/bin/gcc-force-options %asan_force_options -fno-common # Add ASan-related macros cat >> /usr/lib/rpm/tizen_macros << EOF @@ -673,7 +675,9 @@ EOF %preun -n asan-force-options # Restore read-only mode chmod a-w /usr/bin -[ -d /emul/ ] && chmod a-w /emul/usr/bin/ && chmod a-w /emul/home/abuild/rpmbuild/BUILD/gcc-%{version}/obj/gcc/ +chmod a-w %{libsubdir} +[ -d /emul/ ] && chmod a-w /emul/usr/bin/ && chmod a-w /emul/home/abuild/rpmbuild/BUILD/gcc-%{version}/obj/gcc/ \ + && find -L /emul/usr/*/gcc -name 'collect2' | xargs dirname | xargs chmod a-w /usr/bin/gcc-unforce-options %package -n ubsan-force-options @@ -688,7 +692,9 @@ Scripts for UBSan instrumentation %post -n ubsan-force-options # Change mode to allow all users to run gcc-force/unforce-options chmod a+w /usr/bin -[ -d /emul/ ] && chmod a+w /emul/usr/bin/ && chmod a+w /emul/home/abuild/rpmbuild/BUILD/gcc-%{version}/obj/gcc/ +chmod a+w %{libsubdir} +[ -d /emul/ ] && chmod a+w /emul/usr/bin/ && chmod a+w /emul/home/abuild/rpmbuild/BUILD/gcc-%{version}/obj/gcc/ \ + && find -L /emul/usr/*/gcc -name 'collect2' | xargs dirname | xargs chmod a+w /usr/bin/gcc-force-options %ubsan_force_options # Add UBSan-related macros cat >> /usr/lib/rpm/tizen_macros << EOF @@ -702,7 +708,9 @@ EOF %preun -n ubsan-force-options # Restore read-only mode chmod a-w /usr/bin -[ -d /emul/ ] && chmod a-w /emul/usr/bin/ && chmod a-w /emul/home/abuild/rpmbuild/BUILD/gcc-%{version}/obj/gcc/ +chmod a-w %{libsubdir} +[ -d /emul/ ] && chmod a-w /emul/usr/bin/ && chmod a-w /emul/home/abuild/rpmbuild/BUILD/gcc-%{version}/obj/gcc/ \ + && find -L /emul/usr/*/gcc -name 'collect2' | xargs dirname | xargs chmod a-w /usr/bin/gcc-unforce-options %package -n ubsan-build-env @@ -729,7 +737,9 @@ Scripts for LSan instrumentation %post -n lsan-force-options # Change mode to allow all users to run gcc-force/unforce-options chmod a+w /usr/bin -[ -d /emul/ ] && chmod a+w /emul/usr/bin/ && chmod a+w /emul/home/abuild/rpmbuild/BUILD/gcc-%{version}/obj/gcc/ +chmod a+w %{libsubdir} +[ -d /emul/ ] && chmod a+w /emul/usr/bin/ && chmod a+w /emul/home/abuild/rpmbuild/BUILD/gcc-%{version}/obj/gcc/ \ + && find -L /emul/usr/*/gcc -name 'collect2' | xargs dirname | xargs chmod a+w /usr/bin/gcc-force-options %lsan_force_options # Add LSan-related macros cat >> /usr/lib/rpm/tizen_macros << EOF @@ -743,7 +753,9 @@ EOF %preun -n lsan-force-options # Restore read-only mode chmod a-w /usr/bin -[ -d /emul/ ] && chmod a-w /emul/usr/bin/ && chmod a-w /emul/home/abuild/rpmbuild/BUILD/gcc-%{version}/obj/gcc/ +chmod a-w %{libsubdir} +[ -d /emul/ ] && chmod a-w /emul/usr/bin/ && chmod a-w /emul/home/abuild/rpmbuild/BUILD/gcc-%{version}/obj/gcc/ \ + && find -L /emul/usr/*/gcc -name 'collect2' | xargs dirname | xargs chmod a-w /usr/bin/gcc-unforce-options [ -d /emul/ ] && chmod a-w /emul/usr/bin/ diff --git a/packaging/gcc-force-options b/packaging/gcc-force-options index 34f4945..0dfdd9a 100644 --- a/packaging/gcc-force-options +++ b/packaging/gcc-force-options @@ -14,27 +14,64 @@ EOF exit 1 fi -FLAGS="$@" - if [ $(find $(dirname $0) -name \*-real | wc -l) -gt 0 ]; then echo >&2 "$(basename $0): directory was already processed, aborting" exit 1 fi +FLAGS="" +LD_FLAGS="" + +function divide_flags { + NEED_LIB_NAME="N" + for f in "$@"; do + case $f in + -l) + NEED_LIB_NAME="Y" + ;; + + -l*) + LDFLAGS="$LDFLAGS $f" + ;; + + -Wl,*) + LDFLAGS="$LDFLAGS ${f:4}" + ;; + + *) + if [ "$NEED_LIB_NAME" = "Y" ]; then + LDFLAGS="$LDFLAGS -l$f" + NEED_LIB_NAME="N" + else + FLAGS="$FLAGS $f" + fi + esac + done +} + case "$1" in prepend) shift - PREFLAGS="$@" + divide_flags $@ + PREFLAGS=$FLAGS POSTFLAGS= + LD_PREFLAGS=$LDFLAGS + LD_POSTFLAGS= ;; append) shift + divide_flags $@ PREFLAGS= - POSTFLAGS="$@" + POSTFLAGS=$FLAGS + LD_PREFLAGS= + LD_POSTFLAGS=$LDFLAGS ;; *) + divide_flags $@ PREFLAGS= - POSTFLAGS="$@" + POSTFLAGS=$FLAGS + LD_PREFLAGS= + LD_POSTFLAGS=$LDFLAGS ;; esac @@ -50,7 +87,9 @@ elif ! echo "\$@" | grep -q -e __KERNEL__ -e \-nostdlib; then # Use readlink in order to follow symlinks if any \$(readlink -f \$0)-real $PREFLAGS "\$@" $POSTFLAGS else - \$(readlink -f \$0)-real "\$@" + # -Wl,--tizen-no-force-options is used to tell collect2 to not add force + # options. It will be removed in collect2. + \$(readlink -f \$0)-real "\$@" -Wl,--tizen-no-force-options fi EOF chmod +x $TMP @@ -60,11 +99,31 @@ find -L $(dirname $0) -type f -a -perm -a=x | grep -E '(gcc|g\+\+|c\+\+)$' | whi cp $TMP $tool done +LD_TMP=$(pwd)/ld_tmp.$$ +cat > $LD_TMP << EOF +#!/bin/sh +if ! echo "\$@" | grep -q -e \-\-tizen\-no\-force\-options; then + # Use readlink in order to follow symlinks if any + \$(readlink -f \$0)-real $LD_PREFLAGS "\$@" $LD_POSTFLAGS +else + # Remove --tizen-no-force-options from the argument list + FLAGS=\$(echo \$@ | sed -e 's/--tizen-no-force-options//g') + \$(readlink -f \$0)-real \$FLAGS +fi +EOF +chmod +x $LD_TMP + +find -L /usr/*/gcc -type f -a -perm -a=x -name 'collect2' | while read tool; do + mv $tool $tool-real + cp $LD_TMP $tool +done + if [ -d /emul ]; then - find -L /emul -type f -a -perm -a=x | grep -E '(gcc|g\+\+|c\+\+)$' | while read tool; do + find -L /emul -type f -a -perm -a=x | grep -E '(gcc|g\+\+|c\+\+|collect2)$' | while read tool; do ln -sf $(basename $tool) $tool-real done fi rm $TMP +rm $LD_TMP diff --git a/packaging/gcc-unforce-options b/packaging/gcc-unforce-options index cf36d04..7e85b75 100644 --- a/packaging/gcc-unforce-options +++ b/packaging/gcc-unforce-options @@ -7,7 +7,7 @@ if [ $# -gt 0 ]; then exit 1 fi -find $(dirname $0) -name \*-real | while read tool_real; do +find $(dirname $0) /usr/*/gcc -name \*-real | while read tool_real; do tool=$(echo "$tool_real" | sed -e 's/-real$//') mv $tool_real $tool done diff --git a/packaging/linaro-gcc.spec b/packaging/linaro-gcc.spec index 49d2499..5058a99 100644 --- a/packaging/linaro-gcc.spec +++ b/packaging/linaro-gcc.spec @@ -653,7 +653,9 @@ Scripts for ASan instrumentation %post -n asan-force-options # Change mode to allow all users to run gcc-force/unforce-options chmod a+w /usr/bin -[ -d /emul/ ] && chmod a+w /emul/usr/bin/ && chmod a+w /emul/home/abuild/rpmbuild/BUILD/gcc-%{version}/obj/gcc/ +chmod a+w %{libsubdir} +[ -d /emul/ ] && chmod a+w /emul/usr/bin/ && chmod a+w /emul/home/abuild/rpmbuild/BUILD/gcc-%{version}/obj/gcc/ \ + && find -L /emul/usr/*/gcc -name 'collect2' | xargs dirname | xargs chmod a+w /usr/bin/gcc-force-options %asan_force_options -fno-common # Add ASan-related macros cat >> /usr/lib/rpm/tizen_macros << EOF @@ -670,7 +672,9 @@ EOF %preun -n asan-force-options # Restore read-only mode chmod a-w /usr/bin -[ -d /emul/ ] && chmod a-w /emul/usr/bin/ && chmod a-w /emul/home/abuild/rpmbuild/BUILD/gcc-%{version}/obj/gcc/ +chmod a-w %{libsubdir} +[ -d /emul/ ] && chmod a-w /emul/usr/bin/ && chmod a-w /emul/home/abuild/rpmbuild/BUILD/gcc-%{version}/obj/gcc/ \ + && find -L /emul/usr/*/gcc -name 'collect2' | xargs dirname | xargs chmod a-w /usr/bin/gcc-unforce-options %package -n ubsan-force-options @@ -685,7 +689,9 @@ Scripts for UBSan instrumentation %post -n ubsan-force-options # Change mode to allow all users to run gcc-force/unforce-options chmod a+w /usr/bin -[ -d /emul/ ] && chmod a+w /emul/usr/bin/ && chmod a+w /emul/home/abuild/rpmbuild/BUILD/gcc-%{version}/obj/gcc/ +chmod a+w %{libsubdir} +[ -d /emul/ ] && chmod a+w /emul/usr/bin/ && chmod a+w /emul/home/abuild/rpmbuild/BUILD/gcc-%{version}/obj/gcc/ \ + && find -L /emul/usr/*/gcc -name 'collect2' | xargs dirname | xargs chmod a+w /usr/bin/gcc-force-options %ubsan_force_options # Add UBSan-related macros cat >> /usr/lib/rpm/tizen_macros << EOF @@ -699,7 +705,9 @@ EOF %preun -n ubsan-force-options # Restore read-only mode chmod a-w /usr/bin -[ -d /emul/ ] && chmod a-w /emul/usr/bin/ && chmod a-w /emul/home/abuild/rpmbuild/BUILD/gcc-%{version}/obj/gcc/ +chmod a-w %{libsubdir} +[ -d /emul/ ] && chmod a-w /emul/usr/bin/ && chmod a-w /emul/home/abuild/rpmbuild/BUILD/gcc-%{version}/obj/gcc/ \ + && find -L /emul/usr/*/gcc -name 'collect2' | xargs dirname | xargs chmod a-w /usr/bin/gcc-unforce-options %package -n ubsan-build-env @@ -726,7 +734,9 @@ Scripts for LSan instrumentation %post -n lsan-force-options # Change mode to allow all users to run gcc-force/unforce-options chmod a+w /usr/bin -[ -d /emul/ ] && chmod a+w /emul/usr/bin/ && chmod a+w /emul/home/abuild/rpmbuild/BUILD/gcc-%{version}/obj/gcc/ +chmod a+w %{libsubdir} +[ -d /emul/ ] && chmod a+w /emul/usr/bin/ && chmod a+w /emul/home/abuild/rpmbuild/BUILD/gcc-%{version}/obj/gcc/ \ + && find -L /emul/usr/*/gcc -name 'collect2' | xargs dirname | xargs chmod a+w /usr/bin/gcc-force-options %lsan_force_options # Add LSan-related macros cat >> /usr/lib/rpm/tizen_macros << EOF @@ -740,7 +750,9 @@ EOF %preun -n lsan-force-options # Restore read-only mode chmod a-w /usr/bin -[ -d /emul/ ] && chmod a-w /emul/usr/bin/ && chmod a-w /emul/home/abuild/rpmbuild/BUILD/gcc-%{version}/obj/gcc/ +chmod a-w %{libsubdir} +[ -d /emul/ ] && chmod a-w /emul/usr/bin/ && chmod a-w /emul/home/abuild/rpmbuild/BUILD/gcc-%{version}/obj/gcc/ \ + && find -L /emul/usr/*/gcc -name 'collect2' | xargs dirname | xargs chmod a-w /usr/bin/gcc-unforce-options [ -d /emul/ ] && chmod a-w /emul/usr/bin/ -- 2.7.4 From 66898b859383e02b24865b7712423dd7e258bcdc Mon Sep 17 00:00:00 2001 From: Sangmin Seo Date: Wed, 12 Jul 2017 18:37:50 +0900 Subject: [PATCH 10/16] packaging: append -ldl -lpthread to ASan force options. When building for address sanitization, some packages complain about missing symbols due to omitted -ldl or -pthread. This patch appends -ldl and -lpthread to the ASan force options in order to resolve this kind of issue. Note that since -ldl and -lpthread are already needed by libasan, adding them to the ASan force options should not cause any problems. This patch also adds -Wl,--as-needed before -ldl -lpthread in the force options to prevent libdl or libpthread from being linked when unnecessary. Change-Id: Ic50059d4684e15773f56c589cfacda0bc944d955 Signed-off-by: Sangmin Seo --- packaging/gcc-aarch64.spec | 2 +- packaging/gcc-armv7l.spec | 2 +- packaging/linaro-gcc.spec | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packaging/gcc-aarch64.spec b/packaging/gcc-aarch64.spec index ef0e568..b10c27c 100644 --- a/packaging/gcc-aarch64.spec +++ b/packaging/gcc-aarch64.spec @@ -54,7 +54,7 @@ %define libdir %{!?cross:%{_libdir}}%{?cross:%{_prefix}/lib%{?aarch64:64}} %define libsubdir %{libdir}/gcc/%{target_arch}/%{version} -%define asan_force_options -fsanitize-recover=address -fsanitize=address -fno-omit-frame-pointer -Wp,-U_FORTIFY_SOURCE +%define asan_force_options -fsanitize-recover=address -fsanitize=address -fno-omit-frame-pointer -Wp,-U_FORTIFY_SOURCE -Wl,--as-needed -ldl -lpthread %define ubsan_force_options -fsanitize=undefined,bounds-strict,float-divide-by-zero,float-cast-overflow %define lsan_force_options -fsanitize=leak -fno-omit-frame-pointer -Wp,-U_FORTIFY_SOURCE diff --git a/packaging/gcc-armv7l.spec b/packaging/gcc-armv7l.spec index 878d527..cf24112 100644 --- a/packaging/gcc-armv7l.spec +++ b/packaging/gcc-armv7l.spec @@ -54,7 +54,7 @@ %define libdir %{!?cross:%{_libdir}}%{?cross:%{_prefix}/lib%{?aarch64:64}} %define libsubdir %{libdir}/gcc/%{target_arch}/%{version} -%define asan_force_options -fsanitize-recover=address -fsanitize=address -fno-omit-frame-pointer -Wp,-U_FORTIFY_SOURCE +%define asan_force_options -fsanitize-recover=address -fsanitize=address -fno-omit-frame-pointer -Wp,-U_FORTIFY_SOURCE -Wl,--as-needed -ldl -lpthread %define ubsan_force_options -fsanitize=undefined,bounds-strict,float-divide-by-zero,float-cast-overflow %define lsan_force_options -fsanitize=leak -fno-omit-frame-pointer -Wp,-U_FORTIFY_SOURCE diff --git a/packaging/linaro-gcc.spec b/packaging/linaro-gcc.spec index 5058a99..34d9221 100644 --- a/packaging/linaro-gcc.spec +++ b/packaging/linaro-gcc.spec @@ -51,7 +51,7 @@ %define libdir %{!?cross:%{_libdir}}%{?cross:%{_prefix}/lib%{?aarch64:64}} %define libsubdir %{libdir}/gcc/%{target_arch}/%{version} -%define asan_force_options -fsanitize-recover=address -fsanitize=address -fno-omit-frame-pointer -Wp,-U_FORTIFY_SOURCE +%define asan_force_options -fsanitize-recover=address -fsanitize=address -fno-omit-frame-pointer -Wp,-U_FORTIFY_SOURCE -Wl,--as-needed -ldl -lpthread %define ubsan_force_options -fsanitize=undefined,bounds-strict,float-divide-by-zero,float-cast-overflow %define lsan_force_options -fsanitize=leak -fno-omit-frame-pointer -Wp,-U_FORTIFY_SOURCE -- 2.7.4 From d37e8fc0d311abc9e5c9dd153a91ba3731380a00 Mon Sep 17 00:00:00 2001 From: Mikhail Kashkarov Date: Thu, 13 Jul 2017 17:02:39 +0300 Subject: [PATCH 11/16] [TTC-2] Fix asan_symbolize.py for C++ function prototypes detection. Change-Id: Iffa30dce19f99506312a93b79cc8deb05404a82a --- packaging/asan_symbolize.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/asan_symbolize.py b/packaging/asan_symbolize.py index 0ce93b7..235a273 100644 --- a/packaging/asan_symbolize.py +++ b/packaging/asan_symbolize.py @@ -630,7 +630,7 @@ class SymbolizationLoop(object): self.current_line = line.rstrip() #0 0x7f6e35cf2e45 (/blah/foo.so+0x11fe45) stack_trace_line_format = ( - '^( *#([0-9]+) *)(0x[0-9a-f]+)( *in [^ ]+)? *\((.*)\+(0x[0-9a-f]+)\)') + '^( *#([0-9]+) *)(0x[0-9a-f]+)( *in [^/]+)? *\((.*)\+(0x[0-9a-f]+)\)') match = re.match(stack_trace_line_format, line) if not match: return [self.current_line] -- 2.7.4 From b9d84e7357a3afafbf26e6f24325006546763ce6 Mon Sep 17 00:00:00 2001 From: Mikhail Kashkarov Date: Thu, 20 Jul 2017 14:19:13 +0300 Subject: [PATCH 12/16] [TTC-3] Fix asan_symbolize.py output frame numbers. If input line already symbolized and has format '#0 0x7f6e35cf2e45 in func foo:46' - fix internal frame number. packaging/ * asan_symbolized.py (have_line_to_symbolized): New function. Change-Id: I2c52c58f9e2d6dfce709e87dee2abd62b642bcad --- packaging/asan_symbolize.py | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) mode change 100644 => 100755 packaging/asan_symbolize.py diff --git a/packaging/asan_symbolize.py b/packaging/asan_symbolize.py old mode 100644 new mode 100755 index 235a273..f37530b --- a/packaging/asan_symbolize.py +++ b/packaging/asan_symbolize.py @@ -626,13 +626,29 @@ class SymbolizationLoop(object): def process_line_echo(self, line): return [line.rstrip()] - def process_line_posix(self, line): - self.current_line = line.rstrip() - #0 0x7f6e35cf2e45 (/blah/foo.so+0x11fe45) + def have_line_to_symbolize(self, line): + #0 0x7f6e35cf2e45 in func (/blah/foo.so+0x11fe45) stack_trace_line_format = ( '^( *#([0-9]+) *)(0x[0-9a-f]+)( *in [^/]+)? *\((.*)\+(0x[0-9a-f]+)\)') match = re.match(stack_trace_line_format, line) if not match: + # If already symbolized (format below) - fix given frame number + #0 0x7f6e35cf2e45 in func foo:46 + stack_trace_line_format_symbolized = ( + '^( *#([0-9]+) *)(0x[0-9a-f]+)( *in [^/]+)? *(.*)\:([0-9]+)') + match_symbolized = re.match(stack_trace_line_format_symbolized, line); + if match_symbolized: + # Frame number from line + match_frame_number = match_symbolized.group(2) + if (self.frame_no != int(match_frame_number)): + self.current_line = re.sub(match_frame_number, str(self.frame_no), line, count=1) + self.frame_no += 1 + return match + + def process_line_posix(self, line): + self.current_line = line.rstrip() + match = self.have_line_to_symbolize(line) + if not match: return [self.current_line] if DEBUG: print line -- 2.7.4 From 0198572270cc86071b4079253e526873d9cd2dca Mon Sep 17 00:00:00 2001 From: Slava Barinov Date: Fri, 14 Jul 2017 11:25:35 +0300 Subject: [PATCH 13/16] Switch on detect_leaks on 64-bit platforms by default libsanitizer/ * asan/asan_flags.cc: Switch on leak detection for 64-bit target. * lsan/lsan.cc: Likewise. * sanitizer_common/sanitizer_flags.inc: Likewise. Neither the OBS build nor sanitized firmware build are affected. When Tizen application developer enables ASan for his own package only and run it in 64-bit emulator (without any additional setup) ASan will report leaks additionally to all other error messages. Change-Id: Id16017e9bbe5221778330287c707bdf1846f0760 Signed-off-by: Slava Barinov --- libsanitizer/asan/asan_flags.cc | 2 +- libsanitizer/lsan/lsan.cc | 2 +- libsanitizer/sanitizer_common/sanitizer_flags.inc | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/libsanitizer/asan/asan_flags.cc b/libsanitizer/asan/asan_flags.cc index 4f87cd2..93ac1d5 100644 --- a/libsanitizer/asan/asan_flags.cc +++ b/libsanitizer/asan/asan_flags.cc @@ -59,7 +59,7 @@ void InitializeFlags() { { CommonFlags cf; cf.CopyFrom(*common_flags()); - cf.detect_leaks = false; + cf.detect_leaks = (SANITIZER_WORDSIZE == 64); cf.external_symbolizer_path = GetEnv("ASAN_SYMBOLIZER_PATH"); cf.malloc_context_size = kDefaultMallocContextSize; cf.intercept_tls_get_addr = true; diff --git a/libsanitizer/lsan/lsan.cc b/libsanitizer/lsan/lsan.cc index 33051ce..07ca472 100644 --- a/libsanitizer/lsan/lsan.cc +++ b/libsanitizer/lsan/lsan.cc @@ -56,7 +56,7 @@ static void InitializeFlags() { cf.CopyFrom(*common_flags()); cf.external_symbolizer_path = GetEnv("LSAN_SYMBOLIZER_PATH"); cf.malloc_context_size = 30; - cf.detect_leaks = false; + cf.detect_leaks = (SANITIZER_WORDSIZE == 64); cf.exitcode = 0; OverrideCommonFlags(cf); } diff --git a/libsanitizer/sanitizer_common/sanitizer_flags.inc b/libsanitizer/sanitizer_common/sanitizer_flags.inc index 7d95196..88123cc 100644 --- a/libsanitizer/sanitizer_common/sanitizer_flags.inc +++ b/libsanitizer/sanitizer_common/sanitizer_flags.inc @@ -60,7 +60,8 @@ COMMON_FLAG( COMMON_FLAG( int, verbosity, 0, "Verbosity level (0 - silent, 1 - a bit of output, 2+ - more output).") -COMMON_FLAG(bool, detect_leaks, false, "Enable memory leak detection.") +COMMON_FLAG(bool, detect_leaks, (SANITIZER_WORDSIZE == 64), + "Enable memory leak detection.") COMMON_FLAG( bool, leak_check_at_exit, true, "Invoke leak checking in an atexit handler. Has no effect if " -- 2.7.4 From 25d454419a68c0f05aa64d49bb15cda1720809bb Mon Sep 17 00:00:00 2001 From: Slava Barinov Date: Thu, 13 Jul 2017 15:59:38 +0300 Subject: [PATCH 14/16] Remove target-libgfortran from default targets * configure.ac: Make target-libgfortran a configure option. * configure: Regenerate. This fixes on-host build broken by 58909fae. Now OBS build works as usual since it provides --enable-libgfortran explicitly and on-host test builds are not broken with error `GNU Fortran compiler is not working' Change-Id: I39ea37ddb0e52c1e2b43e3d304da1389ce615010 Signed-off-by: Slava Barinov --- configure | 14 +++++++++++++- configure.ac | 9 ++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/configure b/configure index b29a724..a75a44f 100755 --- a/configure +++ b/configure @@ -748,6 +748,7 @@ alphaieee_frag ospace_frag' ac_user_opts=' enable_option_checking +enable_libgfortran with_build_libsubdir with_system_zlib enable_as_accelerator_for @@ -1469,6 +1470,8 @@ Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-libgfortran[=ARG] + build target libgfortran [ARG={default,yes,no}] --enable-as-accelerator-for=ARG build as offload target compiler. Specify offload host triple by ARG @@ -2741,6 +2744,15 @@ libgcj="target-libffi \ target-zlib \ target-libjava" +# libgfortran represents the runtime libraries only used by fortran. +# Check whether --enable-libgfortran was given. +if test "${enable_libgfortran+set}" = set; then : + enableval=$enable_libgfortran; libgfortran="target-libgfortran" +else + libgfortran="" +fi + + # these libraries are built for the target environment, and are built after # the host libraries and the host tools (which may be a cross compiler) # Note that libiberty is not a target library. @@ -2759,7 +2771,7 @@ target_libraries="target-libgcc \ target-libmpx \ target-libssp \ target-libquadmath \ - target-libgfortran \ + ${libgfortran} \ target-boehm-gc \ ${libgcj} \ target-libobjc \ diff --git a/configure.ac b/configure.ac index f23463a..d720c20 100644 --- a/configure.ac +++ b/configure.ac @@ -147,6 +147,13 @@ libgcj="target-libffi \ target-zlib \ target-libjava" +# libgfortran represents the runtime libraries only used by fortran. +AC_ARG_ENABLE(libgfortran, +[AS_HELP_STRING([[--enable-libgfortran[=ARG]]], + [build target libgfortran @<:@ARG={default,yes,no}@:>@])], +libgfortran="target-libgfortran", +libgfortran="") + # these libraries are built for the target environment, and are built after # the host libraries and the host tools (which may be a cross compiler) # Note that libiberty is not a target library. @@ -165,7 +172,7 @@ target_libraries="target-libgcc \ target-libmpx \ target-libssp \ target-libquadmath \ - target-libgfortran \ + ${libgfortran} \ target-boehm-gc \ ${libgcj} \ target-libobjc \ -- 2.7.4 From eb74c5d87bc136704bb62beeb3ba1f901b5f42fe Mon Sep 17 00:00:00 2001 From: timshen Date: Sat, 23 Apr 2016 03:58:37 +0000 Subject: [PATCH 15/16] PR libstdc++/70745 * include/bits/regex_executor.tcc (_Executor<>::_M_word_boundary): Fix the match_not_bow and match_not_eow behavior. * testsuite/28_regex/regression.cc: Add testcase. (cherry-picked from commit 566d49d6947f4590609562dd5f33d0e6b24a4267) Change-Id: Ie38f6f857575432c90f9ae17576ddff4c7bc021a git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@235382 138bc75d-0d04-0410-961f-82ee72b054a4 --- libstdc++-v3/ChangeLog | 7 +++++++ libstdc++-v3/include/bits/regex_executor.tcc | 13 ++++++------- libstdc++-v3/testsuite/28_regex/regression.cc | 16 +++++++++++++++- 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 8785436..554cd72 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,10 @@ +2016-04-22 Tim Shen + + PR libstdc++/70745 + * include/bits/regex_executor.tcc (_Executor<>::_M_word_boundary): + Fix the match_not_bow and match_not_eow behavior. + * testsuite/28_regex/regression.cc: Add testcase. + 2017-02-01 Jonathan Wakely PR libstdc++/78346 diff --git a/libstdc++-v3/include/bits/regex_executor.tcc b/libstdc++-v3/include/bits/regex_executor.tcc index 2abd020..6bbcb1b 100644 --- a/libstdc++-v3/include/bits/regex_executor.tcc +++ b/libstdc++-v3/include/bits/regex_executor.tcc @@ -413,6 +413,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION bool _Executor<_BiIter, _Alloc, _TraitsT, __dfs_mode>:: _M_word_boundary() const { + if (_M_current == _M_begin && (_M_flags & regex_constants::match_not_bow)) + return false; + if (_M_current == _M_end && (_M_flags & regex_constants::match_not_eow)) + return false; + bool __left_is_word = false; if (_M_current != _M_begin || (_M_flags & regex_constants::match_prev_avail)) @@ -424,13 +429,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION bool __right_is_word = _M_current != _M_end && _M_is_word(*_M_current); - if (__left_is_word == __right_is_word) - return false; - if (__left_is_word && !(_M_flags & regex_constants::match_not_eow)) - return true; - if (__right_is_word && !(_M_flags & regex_constants::match_not_bow)) - return true; - return false; + return __left_is_word != __right_is_word; } _GLIBCXX_END_NAMESPACE_VERSION diff --git a/libstdc++-v3/testsuite/28_regex/regression.cc b/libstdc++-v3/testsuite/28_regex/regression.cc index c9a3402..d367c8b 100644 --- a/libstdc++-v3/testsuite/28_regex/regression.cc +++ b/libstdc++-v3/testsuite/28_regex/regression.cc @@ -45,7 +45,20 @@ test02() "/ghci" }; auto rx = std::regex(re_str, std::regex_constants::grep | std::regex_constants::icase); - VERIFY(std::regex_search("/abcd", rx)); + VERIFY(regex_search_debug("/abcd", rx)); +} + +void +test03() +{ + bool test __attribute__((unused)) = true; + + VERIFY(regex_match_debug("a.", regex(R"(a\b.)"), regex_constants::match_not_eow)); + VERIFY(regex_match_debug(".a", regex(R"(.\ba)"), regex_constants::match_not_bow)); + VERIFY(regex_search_debug("a", regex(R"(^\b)"))); + VERIFY(regex_search_debug("a", regex(R"(\b$)"))); + VERIFY(!regex_search_debug("a", regex(R"(^\b)"), regex_constants::match_not_bow)); + VERIFY(!regex_search_debug("a", regex(R"(\b$)"), regex_constants::match_not_eow)); } int @@ -53,6 +66,7 @@ main() { test01(); test02(); + test03(); return 0; } -- 2.7.4 From fa348cd817b131784aa313b9b37aa8d3dcbc8f02 Mon Sep 17 00:00:00 2001 From: timshen Date: Sat, 27 Aug 2016 02:03:23 +0000 Subject: [PATCH 16/16] PR libstdc++/77356 * include/bits/regex_compiler.tcc(_M_insert_bracket_matcher, _M_expression_term): Modify to support dash literal. * include/bits/regex_scanner.h: Add dash as a token type to make a different from the mandated dash literal by escaping. * include/bits/regex_scanner.tcc(_M_scan_in_bracket): Emit dash token in bracket expression parsing. * testsuite/28_regex/regression.cc: Add new testcases. (cherry-picked from commit 6f2116bed6e87668a914dc27fff34c7a68576d4e) Change-Id: I8f516ef995f0fb7db479c441c9e7714bab518806 git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@239794 138bc75d-0d04-0410-961f-82ee72b054a4 --- libstdc++-v3/ChangeLog | 11 +++ libstdc++-v3/include/bits/regex_compiler.tcc | 110 +++++++++++++++++--------- libstdc++-v3/include/bits/regex_scanner.h | 5 +- libstdc++-v3/include/bits/regex_scanner.tcc | 4 +- libstdc++-v3/testsuite/28_regex/regression.cc | 23 ++++++ 5 files changed, 111 insertions(+), 42 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 554cd72..c1121c8 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,14 @@ +2016-08-27 Tim Shen + + PR libstdc++/77356 + * include/bits/regex_compiler.tcc(_M_insert_bracket_matcher, + _M_expression_term): Modify to support dash literal. + * include/bits/regex_scanner.h: Add dash as a token type to make + a different from the mandated dash literal by escaping. + * include/bits/regex_scanner.tcc(_M_scan_in_bracket): Emit dash + token in bracket expression parsing. + * testsuite/28_regex/regression.cc: Add new testcases. + 2016-04-22 Tim Shen PR libstdc++/70745 diff --git a/libstdc++-v3/include/bits/regex_compiler.tcc b/libstdc++-v3/include/bits/regex_compiler.tcc index ff69e16..ef6ebdd 100644 --- a/libstdc++-v3/include/bits/regex_compiler.tcc +++ b/libstdc++-v3/include/bits/regex_compiler.tcc @@ -426,13 +426,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION pair __last_char; // Optional<_CharT> __last_char.first = false; if (!(_M_flags & regex_constants::ECMAScript)) - if (_M_try_char()) - { - __matcher._M_add_char(_M_value[0]); - __last_char.first = true; - __last_char.second = _M_value[0]; - } + { + if (_M_try_char()) + { + __last_char.first = true; + __last_char.second = _M_value[0]; + } + else if (_M_match_token(_ScannerT::_S_token_bracket_dash)) + { + __last_char.first = true; + __last_char.second = '-'; + } + } while (_M_expression_term(__last_char, __matcher)); + if (__last_char.first) + __matcher._M_add_char(__last_char.second); __matcher._M_ready(); _M_stack.push(_StateSeqT( *_M_nfa, @@ -449,19 +457,43 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (_M_match_token(_ScannerT::_S_token_bracket_end)) return false; + const auto __push_char = [&](_CharT __ch) + { + if (__last_char.first) + __matcher._M_add_char(__last_char.second); + else + __last_char.first = true; + __last_char.second = __ch; + }; + const auto __flush = [&] + { + if (__last_char.first) + { + __matcher._M_add_char(__last_char.second); + __last_char.first = false; + } + }; + if (_M_match_token(_ScannerT::_S_token_collsymbol)) { auto __symbol = __matcher._M_add_collate_element(_M_value); if (__symbol.size() == 1) - { - __last_char.first = true; - __last_char.second = __symbol[0]; - } + __push_char(__symbol[0]); + else + __flush(); } else if (_M_match_token(_ScannerT::_S_token_equiv_class_name)) - __matcher._M_add_equivalence_class(_M_value); + { + __flush(); + __matcher._M_add_equivalence_class(_M_value); + } else if (_M_match_token(_ScannerT::_S_token_char_class_name)) - __matcher._M_add_character_class(_M_value, false); + { + __flush(); + __matcher._M_add_character_class(_M_value, false); + } + else if (_M_try_char()) + __push_char(_M_value[0]); // POSIX doesn't allow '-' as a start-range char (say [a-z--0]), // except when the '-' is the first or last character in the bracket // expression ([--0]). ECMAScript treats all '-' after a range as a @@ -472,55 +504,55 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Clang (3.5) always uses ECMAScript style even in its POSIX syntax. // // It turns out that no one reads BNFs ;) - else if (_M_try_char()) + else if (_M_match_token(_ScannerT::_S_token_bracket_dash)) { if (!__last_char.first) { - __matcher._M_add_char(_M_value[0]); - if (_M_value[0] == '-' - && !(_M_flags & regex_constants::ECMAScript)) + if (!(_M_flags & regex_constants::ECMAScript)) { if (_M_match_token(_ScannerT::_S_token_bracket_end)) - return false; + { + __push_char('-'); + return false; + } __throw_regex_error( regex_constants::error_range, "Unexpected dash in bracket expression. For POSIX syntax, " "a dash is not treated literally only when it is at " "beginning or end."); } - __last_char.first = true; - __last_char.second = _M_value[0]; + __push_char('-'); } else { - if (_M_value[0] == '-') + if (_M_try_char()) { - if (_M_try_char()) - { - __matcher._M_make_range(__last_char.second , _M_value[0]); - __last_char.first = false; - } - else - { - if (_M_scanner._M_get_token() - != _ScannerT::_S_token_bracket_end) - __throw_regex_error( - regex_constants::error_range, - "Unexpected end of bracket expression."); - __matcher._M_add_char(_M_value[0]); - } + __matcher._M_make_range(__last_char.second, _M_value[0]); + __last_char.first = false; + } + else if (_M_match_token(_ScannerT::_S_token_bracket_dash)) + { + __matcher._M_make_range(__last_char.second, '-'); + __last_char.first = false; } else { - __matcher._M_add_char(_M_value[0]); - __last_char.second = _M_value[0]; + if (_M_scanner._M_get_token() + != _ScannerT::_S_token_bracket_end) + __throw_regex_error( + regex_constants::error_range, + "Character is expected after a dash."); + __push_char('-'); } } } else if (_M_match_token(_ScannerT::_S_token_quoted_class)) - __matcher._M_add_character_class(_M_value, - _M_ctype.is(_CtypeT::upper, - _M_value[0])); + { + __flush(); + __matcher._M_add_character_class(_M_value, + _M_ctype.is(_CtypeT::upper, + _M_value[0])); + } else __throw_regex_error(regex_constants::error_brack, "Unexpected character in bracket expression."); diff --git a/libstdc++-v3/include/bits/regex_scanner.h b/libstdc++-v3/include/bits/regex_scanner.h index 37dea84..ed0b723 100644 --- a/libstdc++-v3/include/bits/regex_scanner.h +++ b/libstdc++-v3/include/bits/regex_scanner.h @@ -43,7 +43,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { public: /// Token types returned from the scanner. - enum _TokenT + enum _TokenT : unsigned { _S_token_anychar, _S_token_ord_char, @@ -73,7 +73,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _S_token_comma, _S_token_dup_count, _S_token_eof, - _S_token_unknown + _S_token_bracket_dash, + _S_token_unknown = -1u }; protected: diff --git a/libstdc++-v3/include/bits/regex_scanner.tcc b/libstdc++-v3/include/bits/regex_scanner.tcc index fedba09..a734bb1 100644 --- a/libstdc++-v3/include/bits/regex_scanner.tcc +++ b/libstdc++-v3/include/bits/regex_scanner.tcc @@ -210,7 +210,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION auto __c = *_M_current++; - if (__c == '[') + if (__c == '-') + _M_token = _S_token_bracket_dash; + else if (__c == '[') { if (_M_current == _M_end) __throw_regex_error(regex_constants::error_brack, diff --git a/libstdc++-v3/testsuite/28_regex/regression.cc b/libstdc++-v3/testsuite/28_regex/regression.cc index d367c8b..fac7fa2 100644 --- a/libstdc++-v3/testsuite/28_regex/regression.cc +++ b/libstdc++-v3/testsuite/28_regex/regression.cc @@ -61,12 +61,35 @@ test03() VERIFY(!regex_search_debug("a", regex(R"(\b$)"), regex_constants::match_not_eow)); } +// PR libstdc++/77356 +void +test04() +{ + bool test __attribute__((unused)) = true; + + static const char* kNumericAnchor ="(\\$|usd)(usd|\\$|to|and|up to|[0-9,\\.\\-\\sk])+"; + const std::regex re(kNumericAnchor); + (void)re; +} + +void +test05() +{ + bool test __attribute__((unused)) = true; + + VERIFY(regex_match_debug("!", std::regex("[![:alnum:]]"))); + VERIFY(regex_match_debug("-", std::regex("[a-]", regex_constants::basic))); + VERIFY(regex_match_debug("-", std::regex("[a-]"))); +} + int main() { test01(); test02(); test03(); + test04(); + test05(); return 0; } -- 2.7.4