Skip to content

Commit 23a683a

Browse files
authored
bpo-36618: Add -fmax-type-align=8 flag for clang (GH-12809)
Add -fmax-type-align=8 to CFLAGS when clang compiler is detected. The pymalloc memory allocator aligns memory on 8 bytes. On x86-64, clang expects alignment on 16 bytes by default and so uses MOVAPS instruction which can lead to segmentation fault. Instruct clang that Python is limited to alignemnt on 8 bytes to use MOVUPS instruction instead: slower but don't trigger a SIGSEGV if the memory is not aligned on 16 bytes. Sadly, the flag must be expected to CFLAGS and not just CFLAGS_NODIST, since third party C extensions can have the same issue.
1 parent 606c66a commit 23a683a

File tree

3 files changed

+65
-26
lines changed

3 files changed

+65
-26
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Add ``-fmax-type-align=8`` to CFLAGS when clang compiler is detected. The
2+
pymalloc memory allocator aligns memory on 8 bytes. On x86-64, clang expects
3+
alignment on 16 bytes by default and so uses MOVAPS instruction which can
4+
lead to segmentation fault. Instruct clang that Python is limited to
5+
alignemnt on 8 bytes to use MOVUPS instruction instead: slower but don't
6+
trigger a SIGSEGV if the memory is not aligned on 16 bytes. Sadly, the flag
7+
must be expected to ``CFLAGS`` and not just ``CFLAGS_NODIST``, since third
8+
party C extensions can have the same issue.

configure

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6813,6 +6813,19 @@ esac
68136813
# compiler and platform. BASECFLAGS tweaks need to be made even if the
68146814
# user set OPT.
68156815

6816+
case $CC in
6817+
*clang*)
6818+
cc_is_clang=1
6819+
;;
6820+
*)
6821+
if $CC --version 2>&1 | grep -q clang
6822+
then
6823+
cc_is_clang=1
6824+
else
6825+
cc_is_clang=
6826+
fi
6827+
esac
6828+
68166829
# tweak OPT based on compiler and platform, only if the user didn't set
68176830
# it on the command line
68186831

@@ -6826,19 +6839,6 @@ then
68266839
WRAP="-fwrapv"
68276840
fi
68286841

6829-
case $CC in
6830-
*clang*)
6831-
cc_is_clang=1
6832-
;;
6833-
*)
6834-
if $CC --version 2>&1 | grep -q clang
6835-
then
6836-
cc_is_clang=1
6837-
else
6838-
cc_is_clang=
6839-
fi
6840-
esac
6841-
68426842
if test -n "${cc_is_clang}"
68436843
then
68446844
# Clang also needs -fwrapv
@@ -6879,6 +6879,21 @@ then
68796879
esac
68806880
fi
68816881

6882+
if test -n "${cc_is_clang}"
6883+
then
6884+
# bpo-36618: Add -fmax-type-align=8 to CFLAGS when clang compiler is
6885+
# detected. The pymalloc memory allocator aligns memory on 8 bytes. On
6886+
# x86-64, clang expects alignment on 16 bytes by default and so uses MOVAPS
6887+
# instruction which can lead to segmentation fault. Instruct clang that
6888+
# Python is limited to alignemnt on 8 bytes to use MOVUPS instruction
6889+
# instead: slower but don't trigger a SIGSEGV if the memory is not aligned
6890+
# on 16 bytes.
6891+
#
6892+
# Sadly, the flag must be expected to CFLAGS and not just CFLAGS_NODIST,
6893+
# since third party C extensions can have the same issue.
6894+
CFLAGS="$CFLAGS -fmax-type-align=8"
6895+
fi
6896+
68826897

68836898

68846899

@@ -10200,6 +10215,7 @@ fi
1020010215

1020110216

1020210217

10218+
1020310219
if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
1020410220
if test -n "$ac_tool_prefix"; then
1020510221
# Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.

configure.ac

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1464,6 +1464,19 @@ esac
14641464
# compiler and platform. BASECFLAGS tweaks need to be made even if the
14651465
# user set OPT.
14661466

1467+
case $CC in
1468+
*clang*)
1469+
cc_is_clang=1
1470+
;;
1471+
*)
1472+
if $CC --version 2>&1 | grep -q clang
1473+
then
1474+
cc_is_clang=1
1475+
else
1476+
cc_is_clang=
1477+
fi
1478+
esac
1479+
14671480
# tweak OPT based on compiler and platform, only if the user didn't set
14681481
# it on the command line
14691482
AC_SUBST(OPT)
@@ -1477,19 +1490,6 @@ then
14771490
WRAP="-fwrapv"
14781491
fi
14791492

1480-
case $CC in
1481-
*clang*)
1482-
cc_is_clang=1
1483-
;;
1484-
*)
1485-
if $CC --version 2>&1 | grep -q clang
1486-
then
1487-
cc_is_clang=1
1488-
else
1489-
cc_is_clang=
1490-
fi
1491-
esac
1492-
14931493
if test -n "${cc_is_clang}"
14941494
then
14951495
# Clang also needs -fwrapv
@@ -1530,6 +1530,21 @@ then
15301530
esac
15311531
fi
15321532

1533+
if test -n "${cc_is_clang}"
1534+
then
1535+
# bpo-36618: Add -fmax-type-align=8 to CFLAGS when clang compiler is
1536+
# detected. The pymalloc memory allocator aligns memory on 8 bytes. On
1537+
# x86-64, clang expects alignment on 16 bytes by default and so uses MOVAPS
1538+
# instruction which can lead to segmentation fault. Instruct clang that
1539+
# Python is limited to alignemnt on 8 bytes to use MOVUPS instruction
1540+
# instead: slower but don't trigger a SIGSEGV if the memory is not aligned
1541+
# on 16 bytes.
1542+
#
1543+
# Sadly, the flag must be expected to CFLAGS and not just CFLAGS_NODIST,
1544+
# since third party C extensions can have the same issue.
1545+
CFLAGS="$CFLAGS -fmax-type-align=8"
1546+
fi
1547+
15331548
AC_SUBST(BASECFLAGS)
15341549
AC_SUBST(CFLAGS_NODIST)
15351550
AC_SUBST(LDFLAGS_NODIST)

0 commit comments

Comments
 (0)