Bug 191409 - h2ph generates incorrect code for '#if defined A || defined B'
h2ph generates incorrect code for '#if defined A || defined B'
Status: CLOSED CURRENTRELEASE
Product: Red Hat Enterprise Linux 4
Classification: Red Hat
Component: perl (Show other bugs)
4.0
All Linux
medium Severity medium
: ---
: ---
Assigned To: Jason Vas Dias
David Lawrence
http://rt.perl.org/rt3/Ticket/Display...
:
Depends On:
Blocks: 191416 199151
  Show dependency treegraph
 
Reported: 2006-05-11 14:08 EDT by Jason Vas Dias
Modified: 2007-11-30 17:07 EST (History)
1 user (show)

See Also:
Fixed In Version: 5.8.5-34.RHEL4
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2006-10-04 14:48:38 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

  None (edit)
Description Jason Vas Dias 2006-05-11 14:08:28 EDT
Description of problem:

This is perlbug #39130 - see URL .

For cpp statements like :

  #if defined A || defined B

h2ph would generate the code :

  if(defined (defined(&A) ? &A : 0) || defined (defined(&B) ? &B : 0)) {

which is tautologous, as defined(0) is always true .

This turns out to cause real problems on the Linux ppc64 platform,
where "endian-ness" is selectable in the compiler; every inclusion
of "endian.ph", which includes "bits/endian.ph", generates an error:
 
$ perl -e 'require "sys/socket.ph";'
Both BIG_ENDIAN and LITTLE_ENDIAN defined! at
/usr/lib/perl5/5.8.8/ppc-linux-thread-multi/bits/endian.ph line 10.
Compilation failed in require at...

Because h2ph generated this code in ../bits/endian.ph:
if(defined (defined(&__BIG_ENDIAN__) ? &__BIG_ENDIAN__ : 0) || defined
(defined(&_BIG_ENDIAN) ? &_BIG_ENDIAN : 0)) {
    if(defined (defined(&__LITTLE_ENDIAN__) ? &__LITTLE_ENDIAN__ : 0) || defined
(defined(&_LITTLE_ENDIAN) ? &_LITTLE_ENDIAN : 0)) {
        die("Both\ BIG_ENDIAN\ and\ LITTLE_ENDIAN\ defined\!");
    }
For the cpp code in /usr/include/bits/endian.h:
#if defined __BIG_ENDIAN__ || defined _BIG_ENDIAN
# if defined __LITTLE_ENDIAN__ || defined _LITTLE_ENDIAN
#  error Both BIG_ENDIAN and LITTLE_ENDIAN defined!
...

The problem does not happen if the 'defined..' conditions are in parentheses -
ie.
  #if defined(A) || defined(B)
produces correct code:
  if( defined(&A) || defined(&B) )

A trivial fix for this is to simply replace the ': 0' with ': undef' in
h2ph.PL line 517, as with this patch:
--- perl-5.8.8/utils/h2ph.PL~   2006-01-12 17:55:04.000000000 -0500
+++ perl-5.8.8/utils/h2ph.PL    2006-05-11 13:50:04.000000000 -0400
@@ -514,7 +514,7 @@
                }
            } else {
                if ($inif && $new !~ /defined\s*\($/) {
-                   $new .= '(defined(&' . $id . ') ? &' . $id . ' : 0)';
+                   $new .= '(defined(&' . $id . ') ? &' . $id . ' : undef)';
                } elsif (/^\[/) {
                    $new .= " \$$id";
                } else {

Version-Release number of selected component (if applicable):
ALL

How reproducible:
100%

Steps to Reproduce:
On a ppc64 platform with select-able endian-ness:
# perl -e 'require "sys/socket.ph";'
  
Actual results:
Both BIG_ENDIAN and LITTLE_ENDIAN defined! at
/usr/lib/perl5/5.8.8/ppc-linux-thread-multi/bits/endian.ph line 10.
Compilation failed in require at...

Expected results:
no error
Comment 1 Jason Vas Dias 2006-05-11 15:43:02 EDT
Now fixed with perl-5.8.5-34.RHEL4 .

Note You need to log in before you can comment on or make changes to this bug.