diff options
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r-- | gcc/builtins.c | 30 |
1 files changed, 23 insertions, 7 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c index b007498..44b8551 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -6771,6 +6771,7 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode, case BUILT_IN_STRCPY_CHK: case BUILT_IN_STPCPY_CHK: case BUILT_IN_STRNCPY_CHK: + case BUILT_IN_STPNCPY_CHK: case BUILT_IN_STRCAT_CHK: case BUILT_IN_STRNCAT_CHK: case BUILT_IN_SNPRINTF_CHK: @@ -10935,7 +10936,9 @@ fold_builtin_4 (location_t loc, tree fndecl, DECL_FUNCTION_CODE (fndecl)); case BUILT_IN_STRNCPY_CHK: - return fold_builtin_strncpy_chk (loc, arg0, arg1, arg2, arg3, NULL_TREE); + case BUILT_IN_STPNCPY_CHK: + return fold_builtin_stxncpy_chk (loc, arg0, arg1, arg2, arg3, NULL_TREE, + ignore, fcode); case BUILT_IN_STRNCAT_CHK: return fold_builtin_strncat_chk (loc, fndecl, arg0, arg1, arg2, arg3); @@ -12498,6 +12501,7 @@ maybe_emit_chk_warning (tree exp, enum built_in_function fcode) break; case BUILT_IN_STRNCAT_CHK: case BUILT_IN_STRNCPY_CHK: + case BUILT_IN_STPNCPY_CHK: len = CALL_EXPR_ARG (exp, 2); size = CALL_EXPR_ARG (exp, 3); break; @@ -12852,13 +12856,15 @@ fold_builtin_stxcpy_chk (location_t loc, tree fndecl, tree dest, return build_call_expr_loc (loc, fn, 2, dest, src); } -/* Fold a call to the __strncpy_chk builtin. DEST, SRC, LEN, and SIZE +/* Fold a call to the __st{r,p}ncpy_chk builtin. DEST, SRC, LEN, and SIZE are the arguments to the call. If MAXLEN is not NULL, it is maximum - length passed as third argument. */ + length passed as third argument. IGNORE is true if return value can be + ignored. FCODE is the BUILT_IN_* code of the builtin. */ tree -fold_builtin_strncpy_chk (location_t loc, tree dest, tree src, - tree len, tree size, tree maxlen) +fold_builtin_stxncpy_chk (location_t loc, tree dest, tree src, + tree len, tree size, tree maxlen, bool ignore, + enum built_in_function fcode) { tree fn; @@ -12868,6 +12874,15 @@ fold_builtin_strncpy_chk (location_t loc, tree dest, tree src, || !validate_arg (size, INTEGER_TYPE)) return NULL_TREE; + if (fcode == BUILT_IN_STPNCPY_CHK && ignore) + { + /* If return value of __stpncpy_chk is ignored, + optimize into __strncpy_chk. */ + fn = builtin_decl_explicit (BUILT_IN_STRNCPY_CHK); + if (fn) + return build_call_expr_loc (loc, fn, 4, dest, src, len, size); + } + if (! host_integerp (size, 1)) return NULL_TREE; @@ -12888,8 +12903,9 @@ fold_builtin_strncpy_chk (location_t loc, tree dest, tree src, return NULL_TREE; } - /* If __builtin_strncpy_chk is used, assume strncpy is available. */ - fn = builtin_decl_explicit (BUILT_IN_STRNCPY); + /* If __builtin_st{r,p}ncpy_chk is used, assume st{r,p}ncpy is available. */ + fn = builtin_decl_explicit (fcode == BUILT_IN_STPNCPY_CHK + ? BUILT_IN_STPNCPY : BUILT_IN_STRNCPY); if (!fn) return NULL_TREE; |