Using .macro argument in .error message?
Georg-Johann Lay
avr@gjlay.de
Fri Jun 12 15:16:54 GMT 2026
Am 12.06.26 um 08:38 schrieb Jan Beulich:
> On 11.06.2026 18:14, Georg-Johann Lay via Binutils wrote:
>> Am 11.06.26 um 17:17 schrieb Jan Beulich:
>>> On 11.06.2026 16:54, Georg-Johann Lay wrote:
>>>> Am 11.06.26 um 16:18 schrieb Jan Beulich:
>>>>> On 11.06.2026 15:42, Georg-Johann Lay wrote:
>>>>>> Am 11.06.26 um 15:22 schrieb Jan Beulich:
>>>>>>> On 10.06.2026 11:54, Georg-Johann Lay wrote:
>>>>>>>> Am 10.06.26 um 11:27 schrieb Jan Beulich:
>>>>>>>>> On 07.06.2026 21:16, Georg-Johann Lay via Binutils wrote:
>>>>>>>>>> Test case err.sx:
>>>>>>>>>>
>>>>>>>>>> .macro Test data
>>>>>>>>>> .if \data < 0
>>>>>>>>>> .error "value \data is negative"
>>>>>>>>>> .endif
>>>>>>>>>> .endm
>>>>>>>>>>
>>>>>>>>>> Test -1
>>>>>>>>>>
>>>>>>>>>> $ avr-as err.sx -v
>>>>>>>>>> GNU assembler version 2.45.50 (avr) using BFD version (GNU Binutils)
>>>>>>>>>> 2.45.50.20250718
>>>>>>>>>> err.sx: Assembler messages:
>>>>>>>>>> err.sx: Warning: unknown escape '\d' in string; ignored
>>>>>>>>>> err.sx:3: Error: value -1 is negative
>>>>>>>>>> err.sx:7: Info: macro invoked from here
>>>>>>>>>>
>>>>>>>>>> While the printed error message is as expected, there is a spurious
>>>>>>>>>> warning about using \d in the string.
>>>>>>>>>>
>>>>>>>>>> What am I missing?
>>>>>>>>>>
>>>>>>>>>> As far as I understand, the .error message /must/ be "-quoted.
>>>>>>>>>
>>>>>>>>> Indeed. But AVR is one of the few targets which enable this extra
>>>>>>>>> warning. Why that is or whether it could be changed requires AVR
>>>>>>>>> knowledge, which I don#t have. There's also a surprising set of
>>>>>>>>> characters for which the warning would never appear. I don't know
>>>>>>>>> the history of that set, but it feels pretty arbitrary.
>>>>>>>>
>>>>>>>> Okay, I didn't even notice that it's target specific... The only
>>>>>>>> related place I could find is in gas/config/tc-avr.h:
>>>>>>>>
>>>>>>>> /* If you define this macro, GAS will warn about the use of
>>>>>>>> nonstandard escape sequences in a string. */
>>>>>>>> #define ONLY_STANDARD_ESCAPES
>>>>>>>
>>>>>>> This is it, yes.
>>>>>>>
>>>>>>>> Though whatever the behavior wrt. fishy escapes is, resolution
>>>>>>>> of macro arguments should run prior to that, no?
>>>>>>>
>>>>>>> No. Macros are processed after the scrubber (aka "pre-processor") has
>>>>>>> done its work.
>>>>>>
>>>>>> Whatever the technical limitations are; such a warning makes just no sense.
>>>>>
>>>>> The person who had added it likely was of a different opinion. I'm pretty sure
>>>>> things can be improved, and feel free to send a patch, but justifying such a
>>>>> change will likely require some archeology, not just saying "makes no sense".
>>>>
>>>> What I am trying to say is that warning for an unrecognized escape
>>>> sequence isn't very helpful when the sequence is NOT an escape sequence
>>>> to begin with. In the example, \data is treated as a .macro parameter,
>>>> so there is no unknown escape sequence `\d' anywhere.
>>>
>>> The scrubber can't know this is a macro parameter reference.
>>
>> I understand that the artifact is due to some gas internals finesse.
>>
>> But that doesn't help the user's experience in any way.
>
> Well, yes, but see below - we need a concrete proposal for how to change
> that.
>
>> And it's still fine to warn for unrecognized escapes when there /are/
>> unrecognized escapes, so the tc-avr.h choice makes sense IMHO.
>
> And how do you suggest the scrubber distinguish
>
> .error "value \data is negative"
>
> used in a macro from this used outside (or even inside, but with "data"
> not being a macro parameter)?
Wearing a user's hat:
1) A string is a string.
Just like in C, a string should be a string. And that's actually
what the docs say on \:
| \ anything-else
| Any other character when escaped by \ gives a warning, but
| assembles as if the ‘\’ was not present. The idea is that if
| you used an escape sequence you clearly didn’t want the literal
| interpretation of the following character. However as has no
| other interpretation, so as knows it is giving you the wrong
| code and warns you of the fact.
https://sourceware.org/binutils/docs/as/Strings.html
That is, your
> .error "value \data is negative"
should issue a warning and print "value data is negative".
CPP doesn't touch string literals in macro resolution, so when you
want a macro argument as (a part of) a string, then you have to
stringify it with #. As far as I know, there is nothing like
stringification in .macro. Assuming that a char like ^ works
on all platforms (or is provided by, say, tc-<target>.h),
making \data as a part of a string would then be:
.error "value "^\data" is negative"
This would resolve any ambiguities, and it would follow
GAS's own documentation.
Unfortunately, even though .macro nowhere says that param
resolution applies within strings, it mentions
| .print "\bar \baz"
in a .macro. To make things even worse, " may have semantics that
don't don't means sting delimitation, like in
| .macro sum from=0, to=5
| .long \from
| .if \to-\from
| sum "(\from+1)",\to
| .endif
| .endm
| [...] individual arguments will need to be enclosed in [...] double
| quote " characters. The latter may be the only viable option in
| certain situations, as only double quotes are actually stripped while
| establishing arguments.
And it would require that concatenating strings did work. While
| .string "con""cat"
works outside .macro, it throws an error within .macro.
So this is all a bit of a mess, and I don't see a way to resolve it.
Lest alone considering compatibility with previous versions of Binutils.
Johann
> Just to mention, there more anomalies here - at least:
> - For perhaps a small set of targets: While the "quotechar" static variable
> allows for string quotation by other than '"', the case labels
> circumventing the warning only (and potentially wrongly) cover '"'.
> - Only octal digits (and lower case 'f' and 'b') are excluded.
> To me the only viable solution looks to be to drop that warning altogether;
> this would then limit reporting to next_char_of_string(). Yet then there
> must have been a reason that it was added. And more targets than just AVR
> would be affected. (I'll see about doing the necessary archeology. Which
> may lead to nothing. In the meantime, could you add a respective entry to
> our bugzilla?)
>
> Jan
More information about the Binutils
mailing list