summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pod/perldiag.pod9
-rw-r--r--t/lib/warnings/toke7
-rw-r--r--toke.c25
3 files changed, 26 insertions, 15 deletions
diff --git a/pod/perldiag.pod b/pod/perldiag.pod
index 440b76bfec..11ec27fd80 100644
--- a/pod/perldiag.pod
+++ b/pod/perldiag.pod
@@ -4014,15 +4014,16 @@ discovered.
(P) The regular expression engine got confused by what the regular
expression compiler gave it.
+=item Regexp modifier "/%c" may appear a maximum of twice
+
=item Regexp modifier "/%c" may not appear twice
-(F syntax) The regular expression pattern had one of the
-mutually exclusive modifiers repeated. Remove all but one of the
-occurrences.
+(F syntax) The regular expression pattern had too many occurrences
+of the specified modifier. Remove the extraneous ones.
=item Regexp modifiers "/%c" and "/%c" are mutually exclusive
-(F syntax) The regular expression pattern had more than one of the
+(F syntax) The regular expression pattern had more than one of these
mutually exclusive modifiers. Retain only the modifier that is
supposed to be there.
diff --git a/t/lib/warnings/toke b/t/lib/warnings/toke
index 59dc752dfc..9c33e71204 100644
--- a/t/lib/warnings/toke
+++ b/t/lib/warnings/toke
@@ -960,12 +960,15 @@ EXPECT
# toke.c
use warnings 'syntax' ;
my $a = qr/foo/du;
-$a = qr/foo/laai;
+$a = qr/foo/lai;
$a = qr/foo/lil;
+$a = qr/foo/aia;
+$a = qr/foo/aaia;
no warnings 'syntax' ;
my $a = qr/foo/du;
EXPECT
Regexp modifiers "/d" and "/u" are mutually exclusive at - line 3, near "= "
Regexp modifiers "/l" and "/a" are mutually exclusive at - line 4, near "= "
Regexp modifier "/l" may not appear twice at - line 5, near "= "
-BEGIN not safe after errors--compilation aborted at - line 6.
+Regexp modifier "/a" may appear a maximum of twice at - line 7, near "= "
+BEGIN not safe after errors--compilation aborted at - line 8.
diff --git a/toke.c b/toke.c
index f5f1f8ab2f..c4cda7b324 100644
--- a/toke.c
+++ b/toke.c
@@ -8877,17 +8877,21 @@ S_pmflag(pTHX_ const char* const valid_flags, U32 * pmfl, char** s, char* charse
if (*((*s) + 1) == 'n') {
goto deprecate;
}
- if (*((*s) + 1) == ASCII_RESTRICT_PAT_MOD) {
- /* Doubled modifier implies more restricted */
- set_regex_charset(pmfl, REGEX_ASCII_MORE_RESTRICTED_CHARSET);
- (*s)++;
- }
- else {
+
+ if (! *charset) {
set_regex_charset(pmfl, REGEX_ASCII_RESTRICTED_CHARSET);
}
- if (*charset) { /* Do this after the increment of *s in /aa, so
- the return advances the ptr correctly */
- goto multiple_charsets;
+ else {
+
+ /* Error if previous modifier wasn't an 'a', but if it was, see
+ * if, and accept, a second occurrence (only) */
+ if (*charset != 'a'
+ || get_regex_charset(*pmfl)
+ != REGEX_ASCII_RESTRICTED_CHARSET)
+ {
+ goto multiple_charsets;
+ }
+ set_regex_charset(pmfl, REGEX_ASCII_MORE_RESTRICTED_CHARSET);
}
*charset = c;
break;
@@ -8912,6 +8916,9 @@ S_pmflag(pTHX_ const char* const valid_flags, U32 * pmfl, char** s, char* charse
if (*charset != c) {
yyerror(Perl_form(aTHX_ "Regexp modifiers \"/%c\" and \"/%c\" are mutually exclusive", *charset, c));
}
+ else if (c == 'a') {
+ yyerror("Regexp modifier \"/a\" may appear a maximum of twice");
+ }
else {
yyerror(Perl_form(aTHX_ "Regexp modifier \"/%c\" may not appear twice", c));
}