Bug 83244 - inline assembly does not verify input operands allocation
Summary: inline assembly does not verify input operands allocation
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: inline-asm (show other bugs)
Version: 6.3.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-12-01 15:09 UTC by Andrzej Lichnerowicz
Modified: 2017-12-02 10:03 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
zip file with all the files to reproduce (4.63 KB, application/x-zip-compressed)
2017-12-01 15:09 UTC, Andrzej Lichnerowicz
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Andrzej Lichnerowicz 2017-12-01 15:09:46 UTC
Created attachment 42767 [details]
zip file with all the files to reproduce

on x86 `int` instruction needs to receive `imm8`. g++ allows to pass an input operand in inline assembly as "register" too. Example:

template<unsigned char int_no> void int_test_pass() {
  asm("int %0"
    :
    : "N"(int_no)
    :);
}

called with:
int_test_pass<10>();

results in assembly (cutting out garbage):
  _Z13int_test_passILh10EEvv:
  	int $10

but:
template<unsigned char int_no> void int_test_fail() {
  asm("int %0"
    :
    : "r"(int_no)
    :);
}

quietly results in assembly like this. no errors:
  _Z13int_test_failILh10EEvv:
	movl	$10, %eax
	int %al

which is illigal. I've tested this on:
g++-7 (Ubuntu 7.2.0-1ubuntu1~16.04) 7.2.0                                             
g++-6 (Ubuntu/Linaro 6.3.0-18ubuntu2~16.04) 6.3.0 20170519                            
g++-5 (Ubuntu 5.4.1-2ubuntu1~16.04) 5.4.1 20160904                                    
g++-4.9 (Ubuntu 4.9.4-2ubuntu1~16.04) 4.9.4                                           
g++-4.8 (Ubuntu 4.8.5-4ubuntu2) 4.8.5                                                 
g++-4.7 (Ubuntu/Linaro 4.7.4-3ubuntu12) 4.7.4                                         
g++-4.6 (Ubuntu/Linaro 4.6.4-6ubuntu6) 4.6.4                                          

on all above, this program compiles with no errors on -Wall -Werror.
Clang on the other hands breaks compilation with an error:
  gcc_imm8_bug.cpp:9:7: error: invalid operand for instruction
    asm("int %0"
        ^
  <inline asm>:1:6: note: instantiated into assembly here
          int %al
            ^~~
  1 error generated.
Comment 1 Andreas Schwab 2017-12-01 15:17:43 UTC
It is the responsibility of the user to specify correct constraints.
Comment 2 Andrzej Lichnerowicz 2017-12-01 15:39:15 UTC
The resolution doesn't seem appropriate. GCC is creating invalid assembly, and user should not be held responsible for writing correct code, because why have any warnings and errors at all.

OTOH, it is my mistake, sort of, because GCC when emitting code, not assembly (without -S option), actually warns about it:

$ g++-7 gcc_imm8_bug.cpp -o gcc_imm8_bug.
gcc_imm8_bug.cpp: Assembler messages:
gcc_imm8_bug.cpp:12: Error: operand type mismatch for `int'

only with -S option, it is silent.
again, Clang warns in both cases.
Comment 3 Andrew Pinski 2017-12-01 18:15:50 UTC
GCC does not have an integrated assembler just yet.  There have been talks about one but nothing besides that.  On some targets (AIX for an example), the assembler is the system one and not the GNU binutils one.

It is up to the user to use the correct constraint on the inline-asm such that the assembler does not complain.
Comment 4 Andrzej Lichnerowicz 2017-12-02 10:03:57 UTC
Andrew, thank you for taking the time to shed more light on this. It all makes sense now.