From 7bef86ea74ab6969a4e906f938c6abf0ea90dec7 Mon Sep 17 00:00:00 2001 From: Lena Startseva Date: Fri, 11 Aug 2023 11:55:27 +0700 Subject: [PATCH 1/5] MDEV-31460: main.order_by_pack_big fails with view-protocol Fixed tests: main.order_by_pack_big - disabled view-protocol for some queries because the view is created with wrong column name if column name > 64 symbols --- mysql-test/main/order_by_pack_big.test | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mysql-test/main/order_by_pack_big.test b/mysql-test/main/order_by_pack_big.test index 5e39d9f2988..ec8e0c12c54 100644 --- a/mysql-test/main/order_by_pack_big.test +++ b/mysql-test/main/order_by_pack_big.test @@ -112,9 +112,12 @@ set sort_buffer_size=262144*10; --source include/analyze-format.inc eval analyze format=json $query; flush status; +# Enable view-protocol after fix MDEV-27871 +--disable_view_protocol --disable_ps2_protocol eval $query; --enable_ps2_protocol +--enable_view_protocol show status like '%sort%'; set sort_buffer_size=default; @@ -126,9 +129,12 @@ set sort_buffer_size=32768; --source include/analyze-format.inc eval analyze format=json $query; flush status; +# Enable view-protocol after fix MDEV-27871 +--disable_view_protocol --disable_ps2_protocol eval $query; --enable_ps2_protocol +--enable_view_protocol show status like '%sort%'; set sort_buffer_size=default; From 8bbe3a3cd2bac614bcbfcf733249d6d37e911a58 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Mon, 10 Jul 2023 12:15:30 +1000 Subject: [PATCH 2/5] MDEV-21194: mariadb-install-db doesn't properly grant proxy privileges to all created user accounts mariadb-install-db --auth-root-authentication-method=normal created 4 root accounts by default, but only two of these had PROXY privilege granted. mariadb-install-db (default option --auth-root-authentication-method=socket) as non-root user also didn't grant PROXY priv to the created nonroot@localhost user. To fix this, in mysql_system_tables_data.sql, we re-use tmp_user_nopasswd as this contains the list of all root users. REPLACE INTO tmp_proxies_priv SELECT @current_hostname, IFNULL(@auth_root_socket, 'root') creates the $user@$current_host but will not error if @auth_root_socket is null. Note @current_hostname lines are filtered out with --cross-bootstrap in mariadb-install-db so it was needed to include this expression for consistency. Like the existing mysql_system_tables.sql is used to create teh $user@localhost proxies_priv. Test cases roles.acl_statistics, perfschema,privilege_table_io depends on the number of proxy users. After: --auth-root-authentication-method=normal: MariaDB [mysql]> select * from global_priv; +-----------+-------------+--------------------------------------------------------------------------------------------------------------------------+ | Host | User | Priv | +-----------+-------------+--------------------------------------------------------------------------------------------------------------------------+ | localhost | mariadb.sys | {"access":0,"plugin":"mysql_native_password","authentication_string":"","account_locked":true,"password_last_changed":0} | | localhost | root | {"access":18446744073709551615} | | bark | root | {"access":18446744073709551615} | | 127.0.0.1 | root | {"access":18446744073709551615} | | ::1 | root | {"access":18446744073709551615} | | localhost | | {} | | bark | | {} | +-----------+-------------+--------------------------------------------------------------------------------------------------------------------------+ 7 rows in set (0.001 sec) MariaDB [mysql]> select * from proxies_priv; +-----------+------+--------------+--------------+------------+---------+---------------------+ | Host | User | Proxied_host | Proxied_user | With_grant | Grantor | Timestamp | +-----------+------+--------------+--------------+------------+---------+---------------------+ | localhost | root | | | 1 | | 2023-07-10 12:12:24 | | 127.0.0.1 | root | | | 1 | | 2023-07-10 12:12:24 | | ::1 | root | | | 1 | | 2023-07-10 12:12:24 | | bark | root | | | 1 | | 2023-07-10 12:12:24 | +-----------+------+--------------+--------------+------------+---------+---------------------+ --auth-root-authentication-method=socket: MariaDB [mysql]> select * from proxies_priv; +-----------+------+--------------+--------------+------------+---------+---------------------+ | Host | User | Proxied_host | Proxied_user | With_grant | Grantor | Timestamp | +-----------+------+--------------+--------------+------------+---------+---------------------+ | localhost | root | | | 1 | | 2023-07-10 12:11:55 | | localhost | dan | | | 1 | | 2023-07-10 12:11:55 | | bark | dan | | | 1 | | 2023-07-10 12:11:55 | +-----------+------+--------------+--------------+------------+---------+---------------------+ 3 rows in set (0.017 sec) MariaDB [mysql]> select * from global_priv; +-----------+-------------+--------------------------------------------------------------------------------------------------------------------------------------------+ | Host | User | Priv | +-----------+-------------+--------------------------------------------------------------------------------------------------------------------------------------------+ | localhost | mariadb.sys | {"access":0,"plugin":"mysql_native_password","authentication_string":"","account_locked":true,"password_last_changed":0} | | localhost | root | {"access":18446744073709551615,"plugin":"mysql_native_password","authentication_string":"invalid","auth_or":[{},{"plugin":"unix_socket"}]} | | localhost | dan | {"access":18446744073709551615,"plugin":"mysql_native_password","authentication_string":"invalid","auth_or":[{},{"plugin":"unix_socket"}]} | | localhost | | {} | | bark | | {} | +-----------+-------------+--------------------------------------------------------------------------------------------------------------------------------------------+ 5 rows in set (0.000 sec) MariaDB [mysql]> show grants; +----------------------------------------------------------------------------------------------------------------------------------------+ | Grants for dan@localhost | +----------------------------------------------------------------------------------------------------------------------------------------+ | GRANT ALL PRIVILEGES ON *.* TO `dan`@`localhost` IDENTIFIED VIA mysql_native_password USING 'invalid' OR unix_socket WITH GRANT OPTION | | GRANT PROXY ON ''@'%' TO 'dan'@'localhost' WITH GRANT OPTION | +----------------------------------------------------------------------------------------------------------------------------------------+ --- mysql-test/suite/perfschema/r/privilege_table_io.result | 2 ++ mysql-test/suite/roles/acl_statistics.result | 8 ++++---- scripts/mysql_system_tables.sql | 1 + scripts/mysql_system_tables_data.sql | 6 +++--- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/mysql-test/suite/perfschema/r/privilege_table_io.result b/mysql-test/suite/perfschema/r/privilege_table_io.result index fd56d3e1776..553744431e3 100644 --- a/mysql-test/suite/perfschema/r/privilege_table_io.result +++ b/mysql-test/suite/perfschema/r/privilege_table_io.result @@ -108,6 +108,8 @@ wait/io/table/sql/handler handler.cc: TABLE mysql db fetch NULL wait/io/table/sql/handler handler.cc: TABLE mysql proxies_priv fetch NULL wait/io/table/sql/handler handler.cc: TABLE mysql proxies_priv fetch NULL wait/io/table/sql/handler handler.cc: TABLE mysql proxies_priv fetch NULL +wait/io/table/sql/handler handler.cc: TABLE mysql proxies_priv fetch NULL +wait/io/table/sql/handler handler.cc: TABLE mysql proxies_priv fetch NULL wait/io/table/sql/handler handler.cc: TABLE mysql roles_mapping fetch NULL wait/io/table/sql/handler handler.cc: TABLE mysql tables_priv fetch NULL wait/io/table/sql/handler handler.cc: TABLE mysql tables_priv fetch NULL diff --git a/mysql-test/suite/roles/acl_statistics.result b/mysql-test/suite/roles/acl_statistics.result index f43f692cc48..172d011400b 100644 --- a/mysql-test/suite/roles/acl_statistics.result +++ b/mysql-test/suite/roles/acl_statistics.result @@ -6,7 +6,7 @@ Acl_function_grants 0 Acl_procedure_grants 0 Acl_package_spec_grants 0 Acl_package_body_grants 0 -Acl_proxy_users 2 +Acl_proxy_users 4 Acl_role_grants 0 Acl_roles 0 Acl_table_grants 1 @@ -25,7 +25,7 @@ PROCEDURE_GRANTS 0 SELECT count(*) PROXY_USERS from mysql.proxies_priv; PROXY_USERS -2 +4 SELECT count(*) ROLE_GRANTS from mysql.roles_mapping; ROLE_GRANTS 0 @@ -71,7 +71,7 @@ Acl_function_grants 3 Acl_procedure_grants 2 Acl_package_spec_grants 0 Acl_package_body_grants 0 -Acl_proxy_users 3 +Acl_proxy_users 5 Acl_role_grants 4 Acl_roles 2 Acl_table_grants 3 @@ -90,7 +90,7 @@ PROCEDURE_GRANTS 2 SELECT count(*) PROXY_USERS from mysql.proxies_priv; PROXY_USERS -3 +5 SELECT count(*) ROLE_GRANTS from mysql.roles_mapping; ROLE_GRANTS 4 diff --git a/scripts/mysql_system_tables.sql b/scripts/mysql_system_tables.sql index 26639f613de..300210c48ab 100644 --- a/scripts/mysql_system_tables.sql +++ b/scripts/mysql_system_tables.sql @@ -303,6 +303,7 @@ set @had_proxies_priv_table= @@warning_count != 0; -- and for upgrades CREATE TEMPORARY TABLE tmp_proxies_priv LIKE proxies_priv; INSERT INTO tmp_proxies_priv VALUES ('localhost', 'root', '', '', TRUE, '', now()); +REPLACE INTO tmp_proxies_priv SELECT 'localhost',IFNULL(@auth_root_socket, 'root'), '', '', TRUE, '', now() FROM DUAL; INSERT INTO proxies_priv SELECT * FROM tmp_proxies_priv WHERE @had_proxies_priv_table=0; DROP TABLE tmp_proxies_priv; diff --git a/scripts/mysql_system_tables_data.sql b/scripts/mysql_system_tables_data.sql index ab3dd704d2e..b7cab1e17f2 100644 --- a/scripts/mysql_system_tables_data.sql +++ b/scripts/mysql_system_tables_data.sql @@ -47,9 +47,9 @@ IF @auth_root_socket is not null THEN INSERT INTO global_priv SELECT * FROM tmp_user_nopasswd WHERE @had_user_table=0 AND @auth_root_socket IS NULL; INSERT INTO global_priv SELECT * FROM tmp_user_socket WHERE @had_user_table=0 AND @auth_root_socket IS NOT NULL; -DROP TABLE tmp_user_nopasswd, tmp_user_socket; CREATE TEMPORARY TABLE tmp_proxies_priv LIKE proxies_priv; -INSERT INTO tmp_proxies_priv SELECT @current_hostname, 'root', '', '', TRUE, '', now() FROM DUAL WHERE @current_hostname != 'localhost'; +INSERT INTO tmp_proxies_priv SELECT Host, User, '', '', TRUE, '', now() FROM tmp_user_nopasswd WHERE Host != 'localhost' AND @auth_root_socket IS NULL; +REPLACE INTO tmp_proxies_priv SELECT @current_hostname, IFNULL(@auth_root_socket, 'root'), '', '', TRUE, '', now() FROM DUAL WHERE @current_hostname != 'localhost'; INSERT INTO proxies_priv SELECT * FROM tmp_proxies_priv WHERE @had_proxies_priv_table=0; -DROP TABLE tmp_proxies_priv; +DROP TABLE tmp_user_nopasswd, tmp_user_socket, tmp_proxies_priv; From 68353dc92a7b933fe4229337256c98b298115e45 Mon Sep 17 00:00:00 2001 From: Dmitry Shulga Date: Tue, 19 Sep 2023 08:57:36 +0700 Subject: [PATCH 3/5] MDEV-23902: MariaDB crash on calling function On creation of a VIEW that depends on a stored routine an instance of the class Item_func_sp is allocated on a memory root of SP statement. It happens since mysql_make_view() calls the method THD::activate_stmt_arena_if_needed() before parsing definition of the view. On the other hand, when sp_head's rcontext is created an instance of the class Field referenced by the data member Item_func_sp::result_field is allocated on the Item_func_sp's Query_arena (call arena) that set up inside the method Item_sp::execute_impl just before calling the method sp_head::execute_function() On return from the method sp_head::execute_function() all items allocated on the Item_func_sp's Query_arena are released and its memory root is freed (see implementation of the method Item_sp::execute_impl). As a consequence, the pointer Item_func_sp::result_field references to the deallocated memory. Later, when the method sp_head::execute cleans up items allocated for just executed SP instruction the method Item_func_sp::cleanup is invoked and tries to delete an object referenced by data member Item_func_sp::result_field that points to already deallocated memory, that results in a server abnormal termination. To fix the issue the current active arena shouldn't be switched to a statement arena inside the function mysql_make_view() that invoked indirectly by the method sp_head::rcontext_create. It is implemented by introducing the new Query_arena's state STMT_SP_QUERY_ARGUMENTS that is set when explicit Query_arena is created for placing SP arguments and other caller's side items used during SP execution. Then the method THD::activate_stmt_arena_if_needed() checks Query_arena's state and returns immediately without switching to statement's arena. --- mysql-test/main/sp.result | 25 +++++++++++++++++++++++++ mysql-test/main/sp.test | 32 ++++++++++++++++++++++++++++++++ sql/item.cc | 2 +- sql/sql_class.h | 23 ++++++++++++++++++++++- 4 files changed, 80 insertions(+), 2 deletions(-) diff --git a/mysql-test/main/sp.result b/mysql-test/main/sp.result index ea8bdecabd4..567597383bb 100644 --- a/mysql-test/main/sp.result +++ b/mysql-test/main/sp.result @@ -8935,5 +8935,30 @@ CREATE TABLE t1 (a INT); CREATE PROCEDURE p1() SELECT 1 FROM t1 PROCEDURE ANALYSE( 10, (SELECT a FROM t1)); ERROR 42000: PROCEDURE does not support subqueries or stored functions DROP TABLE t1; +# +# MDEV-23902: MariaDB crash on calling function +# +CREATE FUNCTION f2 () RETURNS VARCHAR(1) +BEGIN +DECLARE rec1 ROW TYPE OF v1; +SELECT z INTO rec1 FROM v1; +RETURN 1; +END| +CREATE FUNCTION f1 () RETURNS VARCHAR(1) RETURN f2() ; +CREATE FUNCTION f3 () RETURNS VARCHAR(1) RETURN f_not_exist(); +CREATE VIEW v1 AS SELECT f3() z; +SELECT f1(); +ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them +# Check that crash doen't happen in case f3 completes with success. +DROP FUNCTION f3; +CREATE FUNCTION f3 () RETURNS VARCHAR(1) RETURN '!'; +SELECT f1(); +f1() +1 +# Clean up +DROP FUNCTION f1; +DROP FUNCTION f2; +DROP FUNCTION f3; +DROP VIEW v1; # End of 10.4 tests # diff --git a/mysql-test/main/sp.test b/mysql-test/main/sp.test index 84ad4ea7453..c11ea23080b 100644 --- a/mysql-test/main/sp.test +++ b/mysql-test/main/sp.test @@ -10535,5 +10535,37 @@ CREATE PROCEDURE p1() SELECT 1 FROM t1 PROCEDURE ANALYSE( 10, (SELECT a FROM t1) DROP TABLE t1; +--echo # +--echo # MDEV-23902: MariaDB crash on calling function +--echo # + +--delimiter | +CREATE FUNCTION f2 () RETURNS VARCHAR(1) +BEGIN + DECLARE rec1 ROW TYPE OF v1; + SELECT z INTO rec1 FROM v1; + RETURN 1; +END| +--delimiter ; + +CREATE FUNCTION f1 () RETURNS VARCHAR(1) RETURN f2() ; +CREATE FUNCTION f3 () RETURNS VARCHAR(1) RETURN f_not_exist(); +CREATE VIEW v1 AS SELECT f3() z; + +--error ER_VIEW_INVALID +SELECT f1(); + +--echo # Check that crash doen't happen in case f3 completes with success. +DROP FUNCTION f3; +CREATE FUNCTION f3 () RETURNS VARCHAR(1) RETURN '!'; + +SELECT f1(); + +--echo # Clean up +DROP FUNCTION f1; +DROP FUNCTION f2; +DROP FUNCTION f3; +DROP VIEW v1; + --echo # End of 10.4 tests --echo # diff --git a/sql/item.cc b/sql/item.cc index 685fdc2b69f..472cf3ce2fc 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -2840,7 +2840,7 @@ Item_sp::execute_impl(THD *thd, Item **args, uint arg_count) { init_sql_alloc(&sp_mem_root, "Item_sp", MEM_ROOT_BLOCK_SIZE, 0, MYF(0)); *sp_query_arena= Query_arena(&sp_mem_root, - Query_arena::STMT_INITIALIZED_FOR_SP); + Query_arena::STMT_SP_QUERY_ARGUMENTS); } bool err_status= m_sp->execute_function(thd, args, arg_count, diff --git a/sql/sql_class.h b/sql/sql_class.h index 4c172ba8e2a..e96fe300eba 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1070,11 +1070,21 @@ public: Prepared statement: STMT_INITIALIZED -> STMT_PREPARED -> STMT_EXECUTED. Stored procedure: STMT_INITIALIZED_FOR_SP -> STMT_EXECUTED. Other statements: STMT_CONVENTIONAL_EXECUTION never changes. + + Special case for stored procedure arguments: STMT_SP_QUERY_ARGUMENTS + This state never changes and used for objects + whose lifetime is whole duration of function call + (sp_rcontext, it's tables and items. etc). Such objects + should be deallocated after every execution of a stored + routine. Caller's arena/memroot can't be used for + placing such objects since memory allocated on caller's + arena not freed until termination of user's session. */ enum enum_state { STMT_INITIALIZED= 0, STMT_INITIALIZED_FOR_SP= 1, STMT_PREPARED= 2, - STMT_CONVENTIONAL_EXECUTION= 3, STMT_EXECUTED= 4, STMT_ERROR= -1 + STMT_CONVENTIONAL_EXECUTION= 3, STMT_EXECUTED= 4, + STMT_SP_QUERY_ARGUMENTS= 5, STMT_ERROR= -1 }; enum_state state; @@ -4046,6 +4056,17 @@ public: inline Query_arena *activate_stmt_arena_if_needed(Query_arena *backup) { + if (state == Query_arena::STMT_SP_QUERY_ARGUMENTS) + /* + Caller uses the arena with state STMT_SP_QUERY_ARGUMENTS for stored + routine's parameters. Lifetime of these objects spans a lifetime of + stored routine call and freed every time the stored routine execution + has been completed. That is the reason why switching to statement's + arena is not performed for arguments, else we would observe increasing + of memory usage while a stored routine be called over and over again. + */ + return NULL; + /* Use the persistent arena if we are in a prepared statement or a stored procedure statement and we have not already changed to use this arena. From 76b688f100024d74193b6c06eb6d21e459e9325c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 19 Sep 2023 09:31:34 +0300 Subject: [PATCH 4/5] MDEV-30024 InnoDB: tried to purge non-delete-marked of a virtual column prefix row_vers_vc_matches_cluster(): Invoke dtype_get_at_most_n_mbchars() to extract the correct number of bytes corresponding to the number of characters in a virtual column prefix index, just like we do in row_sel_sec_rec_is_for_clust_rec(). The test case would occasionally reproduce the failure when this fix is not present. --- .../suite/gcol/r/innodb_virtual_purge.result | 14 ++++++++++++++ mysql-test/suite/gcol/t/innodb_virtual_purge.test | 14 ++++++++++++++ storage/innobase/row/row0vers.cc | 13 ++++++++++--- 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/mysql-test/suite/gcol/r/innodb_virtual_purge.result b/mysql-test/suite/gcol/r/innodb_virtual_purge.result index ee88527ec2e..82f3523428c 100644 --- a/mysql-test/suite/gcol/r/innodb_virtual_purge.result +++ b/mysql-test/suite/gcol/r/innodb_virtual_purge.result @@ -159,4 +159,18 @@ UNIQUE(pk), KEY(e) ) ENGINE=InnoDB; DROP TABLE t1, t2; +# +# MDEV-30024 InnoDB: tried to purge non-delete-marked record +# of an index on a virtual column prefix +# +CREATE TABLE t(a BINARY(8), b CHAR(8) AS (a) VIRTUAL, KEY(b(4))) +CHARACTER SET utf8 ENGINE=InnoDB; +INSERT INTO t (a) VALUES (''),(''); +UPDATE t SET a = 'x'; +UPDATE t SET a = ''; +SET GLOBAL innodb_max_purge_lag_wait=0; +CHECK TABLE t EXTENDED; +Table Op Msg_type Msg_text +test.t check status OK +DROP TABLE t; SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; diff --git a/mysql-test/suite/gcol/t/innodb_virtual_purge.test b/mysql-test/suite/gcol/t/innodb_virtual_purge.test index c79a817dd4e..49ec48c1c64 100644 --- a/mysql-test/suite/gcol/t/innodb_virtual_purge.test +++ b/mysql-test/suite/gcol/t/innodb_virtual_purge.test @@ -172,5 +172,19 @@ dec $n; DROP TABLE t1, t2; +--echo # +--echo # MDEV-30024 InnoDB: tried to purge non-delete-marked record +--echo # of an index on a virtual column prefix +--echo # + +CREATE TABLE t(a BINARY(8), b CHAR(8) AS (a) VIRTUAL, KEY(b(4))) +CHARACTER SET utf8 ENGINE=InnoDB; +INSERT INTO t (a) VALUES (''),(''); +UPDATE t SET a = 'x'; +UPDATE t SET a = ''; +SET GLOBAL innodb_max_purge_lag_wait=0; +CHECK TABLE t EXTENDED; +DROP TABLE t; + --source include/wait_until_count_sessions.inc SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; diff --git a/storage/innobase/row/row0vers.cc b/storage/innobase/row/row0vers.cc index 9d2e6654c46..1a156ed997c 100644 --- a/storage/innobase/row/row0vers.cc +++ b/storage/innobase/row/row0vers.cc @@ -739,9 +739,16 @@ row_vers_vc_matches_cluster( && (!compare[v_col->v_pos])) { if (ind_field->prefix_len != 0 - && !dfield_is_null(field2) - && field2->len > ind_field->prefix_len) { - field2->len = ind_field->prefix_len; + && !dfield_is_null(field2)) { + field2->len = unsigned( + dtype_get_at_most_n_mbchars( + field2->type.prtype, + field2->type.mbminlen, + field2->type.mbmaxlen, + ind_field->prefix_len, + field2->len, + static_cast + (field2->data))); } /* The index field mismatch */ From d0abbdf56e11ccc88447c1dc80caaf355c94be3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 19 Sep 2023 10:14:03 +0300 Subject: [PATCH 5/5] MDEV-31605 cmake/stack_direction.c does not work correctly on clang 16 According to commit ea56841997995283f04e85e957c8d7f3159c85b0 the stack normally grows downwards, except on HP PA-RISC where it grows upwards. Because determining the stack direction is not possible in a portable way, let us determine the default STACK_DIRECTION in CMake based on the ISA. On clang 16.0.6 running on and targeting AMD64, STACK_DIRECTION=1 is being incorrectly detected, causing the failure of a number of tests. --- cmake/stack_direction.c | 33 --------------------------------- configure.cmake | 24 +++++------------------- 2 files changed, 5 insertions(+), 52 deletions(-) delete mode 100644 cmake/stack_direction.c diff --git a/cmake/stack_direction.c b/cmake/stack_direction.c deleted file mode 100644 index 1f7a5d0b135..00000000000 --- a/cmake/stack_direction.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - Copyright (c) 2009 Sun Microsystems, Inc. - Use is subject to license terms. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */ - -/* Check stack direction (0-down, 1-up) */ -int f(int *a) -{ - int b; - return(&b > a)?1:0; -} -/* - Prevent compiler optimizations by calling function - through pointer. -*/ -volatile int (*ptr_f)(int *) = f; -int main() -{ - int a; - return ptr_f(&a); -} diff --git a/configure.cmake b/configure.cmake index 475fd250329..55affd756d3 100644 --- a/configure.cmake +++ b/configure.cmake @@ -672,25 +672,11 @@ int main() } " HAVE_PTHREAD_YIELD_ZERO_ARG) -IF(NOT STACK_DIRECTION) - IF(CMAKE_CROSSCOMPILING) - MESSAGE(FATAL_ERROR - "STACK_DIRECTION is not defined. Please specify -DSTACK_DIRECTION=1 " - "or -DSTACK_DIRECTION=-1 when calling cmake.") - ELSE() - TRY_RUN(STACKDIR_RUN_RESULT STACKDIR_COMPILE_RESULT - ${CMAKE_BINARY_DIR} - ${CMAKE_SOURCE_DIR}/cmake/stack_direction.c - ) - # Test program returns 0 (down) or 1 (up). - # Convert to -1 or 1 - IF(STACKDIR_RUN_RESULT EQUAL 0) - SET(STACK_DIRECTION -1 CACHE INTERNAL "Stack grows direction") - ELSE() - SET(STACK_DIRECTION 1 CACHE INTERNAL "Stack grows direction") - ENDIF() - MESSAGE(STATUS "Checking stack direction : ${STACK_DIRECTION}") - ENDIF() +IF(STACK_DIRECTION) +ELSEIF(CMAKE_SYSTEM_PROCESSOR MATCHES "^(parisc|hppa)") + SET(STACK_DIRECTION 1 CACHE INTERNAL "Stack grows direction") +ELSE() + SET(STACK_DIRECTION -1 CACHE INTERNAL "Stack grows direction") ENDIF() #