Skip to content

Conversation

@tarunprabhu
Copy link
Contributor

These options are supported by the Intel compiler. There are similar options in the IBM compiler as well. Each of the options can be provided more than once. In that case, the last occurence of -fdefault-real-* (respectively -fdefault-integer-*) is used if both -fdefault-real-4 and -fdefault-real-8 are specified. The fdefault.f90 test file was extensively modified. The handling of the option by the driver was removed since testing the handling of the options by -fc1 is sufficient.

Fixes #160252


Notes for reviewers:

This was discussed during the flang call and also in this RFC. There were no objections raised during either the call or in the RFC.

These options are supported by the Intel compiler. There are similar options in
the IBM compiler as well. Each of the options can be provided more than once.
In that case, the last occurence of -fdefault-real-* (respectively
-fdefault-integer-*) is used if both -fdefault-real-4 and -fdefault-real-8 are
specified. The fdefault.f90 test file was extensively modified. The handling of
the option by the driver was removed since testing the handling of the options
by -fc1 is sufficient.

Fixes llvm#160252
@llvmbot llvmbot added clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' flang:driver flang Flang issues not falling into any other category flang:semantics labels Dec 15, 2025
@llvmbot
Copy link
Member

llvmbot commented Dec 15, 2025

@llvm/pr-subscribers-flang-semantics

@llvm/pr-subscribers-clang-driver

Author: Tarun Prabhu (tarunprabhu)

Changes

These options are supported by the Intel compiler. There are similar options in the IBM compiler as well. Each of the options can be provided more than once. In that case, the last occurence of -fdefault-real-* (respectively -fdefault-integer-*) is used if both -fdefault-real-4 and -fdefault-real-8 are specified. The fdefault.f90 test file was extensively modified. The handling of the option by the driver was removed since testing the handling of the options by -fc1 is sufficient.

Fixes #160252


Notes for reviewers:

This was discussed during the flang call and also in this RFC. There were no objections raised during either the call or in the RFC.


Full diff: https://github.com/llvm/llvm-project/pull/172323.diff

6 Files Affected:

  • (modified) clang/include/clang/Options/Options.td (+4)
  • (modified) clang/lib/Driver/ToolChains/Flang.cpp (+2)
  • (modified) flang/lib/Frontend/CompilerInvocation.cpp (+28-8)
  • (modified) flang/test/Driver/fdefault.f90 (+99-31)
  • (modified) flang/test/Driver/frontend-forwarding.f90 (+4)
  • (modified) flang/test/Semantics/numeric_storage_size.f90 (+18)
diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td
index 45c5322351a17..000608134202d 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -7344,6 +7344,10 @@ def fdefault_integer_8 : Flag<["-"],"fdefault-integer-8">, Group<f_Group>,
   HelpText<"Set the default integer and logical kind to an 8 byte wide type">;
 def fdefault_real_8 : Flag<["-"],"fdefault-real-8">, Group<f_Group>,
   HelpText<"Set the default real kind to an 8 byte wide type">;
+def fdefault_integer_4 : Flag<["-"],"fdefault-integer-4">, Group<f_Group>,
+  HelpText<"Set the default integer and logical kind to a 4 byte wide type">;
+def fdefault_real_4 : Flag<["-"],"fdefault-real-4">, Group<f_Group>,
+  HelpText<"Set the default real kind to a 4 byte wide type">;
 def fdisable_real_3 : Flag<["-"],"fdisable-real-3">, Group<f_Group>,
    HelpText<"Disable real(KIND=3) from TargetCharacteristics">, Flags<[HelpHidden]>;
 def fdisable_real_10 : Flag<["-"],"fdisable-real-10">, Group<f_Group>,
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp
index 2f5e93d139858..128a4beaceeb9 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -51,6 +51,8 @@ void Flang::addFortranDialectOptions(const ArgList &Args,
                             options::OPT_fxor_operator,
                             options::OPT_fno_xor_operator,
                             options::OPT_falternative_parameter_statement,
+                            options::OPT_fdefault_integer_4,
+                            options::OPT_fdefault_real_4,
                             options::OPT_fdefault_real_8,
                             options::OPT_fdefault_integer_8,
                             options::OPT_fdefault_double_8,
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index b6c4e6303cdac..dd25cdc0e5707 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -1086,15 +1086,35 @@ static bool parseDialectArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
   }
 
   // -fdefault* family
-  if (args.hasArg(clang::options::OPT_fdefault_real_8)) {
-    res.getDefaultKinds().set_defaultRealKind(8);
-    res.getDefaultKinds().set_doublePrecisionKind(16);
+  if (const llvm::opt::Arg *arg =
+          args.getLastArg(clang::options::OPT_fdefault_real_8,
+                          clang::options::OPT_fdefault_real_4)) {
+    const llvm::opt::Option &opt = arg->getOption();
+    if (opt.matches(clang::options::OPT_fdefault_real_8)) {
+      res.getDefaultKinds().set_defaultRealKind(8);
+      res.getDefaultKinds().set_doublePrecisionKind(16);
+    } else if (opt.matches(clang::options::OPT_fdefault_real_4)) {
+      res.getDefaultKinds().set_defaultRealKind(4);
+      res.getDefaultKinds().set_doublePrecisionKind(8);
+    }
   }
-  if (args.hasArg(clang::options::OPT_fdefault_integer_8)) {
-    res.getDefaultKinds().set_defaultIntegerKind(8);
-    res.getDefaultKinds().set_subscriptIntegerKind(8);
-    res.getDefaultKinds().set_sizeIntegerKind(8);
-    res.getDefaultKinds().set_defaultLogicalKind(8);
+  if (const llvm::opt::Arg *arg =
+          args.getLastArg(clang::options::OPT_fdefault_integer_8,
+                          clang::options::OPT_fdefault_integer_4)) {
+    const llvm::opt::Option &opt = arg->getOption();
+    if (opt.matches(clang::options::OPT_fdefault_integer_8)) {
+      res.getDefaultKinds().set_defaultIntegerKind(8);
+      res.getDefaultKinds().set_subscriptIntegerKind(8);
+      res.getDefaultKinds().set_sizeIntegerKind(8);
+      res.getDefaultKinds().set_defaultLogicalKind(8);
+    } else if (opt.matches(clang::options::OPT_fdefault_integer_4)) {
+      // Note that the subscript integer kind is set to 8 here. If a
+      // default-integer-kind is not provided, it is also set to 8.
+      res.getDefaultKinds().set_defaultIntegerKind(4);
+      res.getDefaultKinds().set_subscriptIntegerKind(8);
+      res.getDefaultKinds().set_sizeIntegerKind(4);
+      res.getDefaultKinds().set_defaultLogicalKind(4);
+    }
   }
   if (args.hasArg(clang::options::OPT_fdefault_double_8)) {
     if (!args.hasArg(clang::options::OPT_fdefault_real_8)) {
diff --git a/flang/test/Driver/fdefault.f90 b/flang/test/Driver/fdefault.f90
index 7ce45b763a240..b879cd56157ed 100644
--- a/flang/test/Driver/fdefault.f90
+++ b/flang/test/Driver/fdefault.f90
@@ -1,46 +1,114 @@
 ! Ensure argument -fdefault* work as expected.
 ! TODO: Add checks when actual codegen is possible for this family
-
-!--------------------------
-! FLANG DRIVER (flang)
-!--------------------------
-! RUN: rm -rf %t/dir-flang  && mkdir -p %t/dir-flang && %flang -fsyntax-only -module-dir %t/dir-flang %s  2>&1
-! RUN: cat %t/dir-flang/m.mod | FileCheck %s --check-prefix=NOOPTION
-! RUN: rm -rf %t/dir-flang  && mkdir -p %t/dir-flang && %flang -fsyntax-only -fdefault-real-8 -module-dir %t/dir-flang %s  2>&1
-! RUN: cat %t/dir-flang/m.mod | FileCheck %s --check-prefix=REAL8
-! RUN: rm -rf %t/dir-flang  && mkdir -p %t/dir-flang && %flang -fsyntax-only -fdefault-real-8 -fdefault-double-8 -module-dir %t/dir-flang %s  2>&1
-! RUN: cat %t/dir-flang/m.mod | FileCheck %s --check-prefix=DOUBLE8
-! RUN: not %flang -fsyntax-only -fdefault-double-8 %s  2>&1 | FileCheck %s --check-prefix=ERROR
-
-!-----------------------------------------
-! FRONTEND FLANG DRIVER (flang -fc1)
-!-----------------------------------------
-! RUN: rm -rf %t/dir-flang  && mkdir -p %t/dir-flang && %flang_fc1 -fsyntax-only -module-dir %t/dir-flang %s  2>&1
-! RUN: cat %t/dir-flang/m.mod | FileCheck %s --check-prefix=NOOPTION
-! RUN: rm -rf %t/dir-flang  && mkdir -p %t/dir-flang && %flang_fc1 -fsyntax-only -fdefault-real-8 -module-dir %t/dir-flang %s  2>&1
-! RUN: cat %t/dir-flang/m.mod | FileCheck %s --check-prefix=REAL8
-! RUN: rm -rf %t/dir-flang  && mkdir -p %t/dir-flang && %flang_fc1 -fsyntax-only -fdefault-real-8 -fdefault-double-8 -module-dir %t/dir-flang %s  2>&1
-! RUN: cat %t/dir-flang/m.mod | FileCheck %s --check-prefix=DOUBLE8
-! RUN: not %flang_fc1 -fsyntax-only -fdefault-double-8 %s  2>&1 | FileCheck %s --check-prefix=ERROR
-
-! NOOPTION: integer(4),parameter::real_kind=4_4
+!
+! RUN: rm -rf %t && mkdir -p %t && \
+! RUN:    %flang_fc1 -fsyntax-only -module-dir %t %s
+! RUN: cat %t/m.mod | FileCheck %s --check-prefix=NOOPTION
+!
+! RUN: rm -rf %t && mkdir -p %t && \
+! RUN:   %flang_fc1 -fsyntax-only -fdefault-integer-4 -module-dir %t %s
+! RUN: cat %t/m.mod | FileCheck %s --check-prefix=INTEGER4
+!
+! RUN: rm -rf %t && mkdir -p %t && \
+! RUN:   %flang_fc1 -fsyntax-only -fdefault-real-4 -module-dir %t %s
+! RUN: cat %t/m.mod | FileCheck %s --check-prefix=REAL4
+!
+! RUN: rm -rf %t && mkdir -p %t && \
+! RUN:   %flang_fc1 -fsyntax-only -fdefault-integer-4 -fdefault-real-4 \
+! RUN:       -module-dir %t %s
+! RUN: cat %t/m.mod | FileCheck %s --check-prefix=BOTH4
+!
+! RUN: rm -rf %t && mkdir -p %t && \
+! RUN:   %flang_fc1 -fsyntax-only -fdefault-integer-8 -module-dir %t %s
+! RUN: cat %t/m.mod | FileCheck %s --check-prefix=INTEGER8
+!
+! RUN: rm -rf %t && mkdir -p %t && \
+! RUN:   %flang -fsyntax-only -fdefault-real-8 -module-dir %t %s
+! RUN: cat %t/m.mod | FileCheck %s --check-prefix=REAL8
+!
+! RUN: rm -rf %t && mkdir -p %t && \
+! RUN:   %flang_fc1 -fsyntax-only -fdefault-integer-8 -fdefault-real-8 \
+! RUN:       -module-dir %t %s
+! RUN: cat %t/m.mod | FileCheck %s --check-prefix=BOTH8
+!
+! RUN: rm -rf %t && mkdir -p %t && \
+! RUN:   %flang_fc1 -fsyntax-only -fdefault-real-8 -fdefault-double-8 \
+! RUN:       -module-dir %t %s
+! RUN: cat %t/m.mod | FileCheck %s --check-prefix=DOUBLE8
+!
+! RUN: not %flang_fc1 -fsyntax-only -fdefault-double-8 %s 2>&1 \
+! RUN:     | FileCheck %s --check-prefix=ERROR
+!
+! The last occurrence of -fdefault-* "wins"
+!
+! RUN: rm -rf %t && mkdir -p %t && \
+! RUN:   %flang_fc1 -fsyntax-only -fdefault-integer-4 -fdefault-integer-8 \
+! RUN:       -module-dir %t %s
+! RUN: cat %t/m.mod | FileCheck %s --check-prefix=INTEGER8
+!
+! RUN: rm -rf %t && mkdir -p %t && \
+! RUN:   %flang_fc1 -fsyntax-only -fdefault-integer-8 -fdefault-integer-4 \
+! RUN:       -module-dir %t %s
+! RUN: cat %t/m.mod | FileCheck %s --check-prefix=INTEGER4
+!
+! RUN: rm -rf %t && mkdir -p %t && \
+! RUN:   %flang_fc1 -fsyntax-only -fdefault-real-4 -fdefault-real-8 \
+! RUN:       -module-dir %t %s
+! RUN: cat %t/m.mod | FileCheck %s --check-prefix=REAL8
+!
+! RUN: rm -rf %t && mkdir -p %t && \
+! RUN:   %flang_fc1 -fsyntax-only -fdefault-real-8 -fdefault-real-4 \
+! RUN:       -module-dir %t %s
+! RUN: cat %t/m.mod | FileCheck %s --check-prefix=REAL4
+!
+! NOOPTION: integer(4),parameter::integer_kind=4_4
 ! NOOPTION-NEXT: intrinsic::kind
+! NOOPTION-NEXT: integer(4),parameter::real_kind=4_4
 ! NOOPTION-NEXT: integer(4),parameter::double_kind=8_4
-
-! REAL8: integer(4),parameter::real_kind=8_4
+!
+! INTEGER4: integer(4),parameter::integer_kind=4_4
+! INTEGER4-NEXT: intrinsic::kind
+! INTEGER4-NEXT: integer(4),parameter::real_kind=4_4
+! INTEGER4-NEXT: integer(4),parameter::double_kind=8_4
+!
+! REAL4: integer(4),parameter::integer_kind=4_4
+! REAL4-NEXT: intrinsic::kind
+! REAL4-NEXT: integer(4),parameter::real_kind=4_4
+! REAL4-NEXT: integer(4),parameter::double_kind=8_4
+!
+! BOTH4: integer(4),parameter::integer_kind=4_4
+! BOTH4-NEXT: intrinsic::kind
+! BOTH4-NEXT: integer(4),parameter::real_kind=4_4
+! BOTH4-NEXT: integer(4),parameter::double_kind=8_4
+!
+! INTEGER8: integer(8),parameter::integer_kind=8_8
+! INTEGER8-NEXT: intrinsic::kind
+! INTEGER8-NEXT: integer(8),parameter::real_kind=4_8
+! INTEGER8-NEXT: integer(8),parameter::double_kind=8_8
+!
+! REAL8: integer(4),parameter::integer_kind=4_4
 ! REAL8-NEXT: intrinsic::kind
+! REAL8-NEXT: integer(4),parameter::real_kind=8_4
 ! REAL8-NEXT: integer(4),parameter::double_kind=16_4
-
-! DOUBLE8: integer(4),parameter::real_kind=8_4
+!
+! BOTH8: integer(8),parameter::integer_kind=8_8
+! BOTH8-NEXT: intrinsic::kind
+! BOTH8-NEXT: integer(8),parameter::real_kind=8_8
+! BOTH8-NEXT: integer(8),parameter::double_kind=16_8
+!
+! DOUBLE8: integer(4),parameter::integer_kind=4_4
 ! DOUBLE8-NEXT: intrinsic::kind
+! DOUBLE8-NEXT: integer(4),parameter::real_kind=8_4
 ! DOUBLE8-NEXT: integer(4),parameter::double_kind=8_4
-
+!
 ! ERROR: Use of `-fdefault-double-8` requires `-fdefault-real-8`
 
 module m
   implicit none
+  integer :: i
   real :: x
   double precision :: y
-  integer, parameter :: real_kind = kind(x)            !-fdefault-real-8
-  integer, parameter :: double_kind = kind(y)          !-fdefault-double-8
+  integer, parameter :: integer_kind = kind(i)         !-fdefault-integer-*
+  integer, parameter :: real_kind = kind(x)            !-fdefault-real-*
+  integer, parameter :: double_kind = kind(y)          !-fdefault-double-*
 end
diff --git a/flang/test/Driver/frontend-forwarding.f90 b/flang/test/Driver/frontend-forwarding.f90
index 952937168c95d..976454f8f2181 100644
--- a/flang/test/Driver/frontend-forwarding.f90
+++ b/flang/test/Driver/frontend-forwarding.f90
@@ -3,6 +3,8 @@
 
 ! RUN: %flang -fsyntax-only -### %s -o %t 2>&1 \
 ! RUN:     -finput-charset=utf-8 \
+! RUN:     -fdefault-integer-4 \
+! RUN:     -fdefault-real-4 \
 ! RUN:     -fdefault-double-8 \
 ! RUN:     -fdefault-integer-8 \
 ! RUN:     -fdefault-real-8 \
@@ -36,6 +38,8 @@
 
 ! CHECK: "-P"
 ! CHECK: "-finput-charset=utf-8"
+! CHECK: "-fdefault-integer-4"
+! CHECK: "-fdefault-real-4"
 ! CHECK: "-fdefault-double-8"
 ! CHECK: "-fdefault-integer-8"
 ! CHECK: "-fdefault-real-8"
diff --git a/flang/test/Semantics/numeric_storage_size.f90 b/flang/test/Semantics/numeric_storage_size.f90
index 720297c0feb30..ee11f3b15d5bf 100644
--- a/flang/test/Semantics/numeric_storage_size.f90
+++ b/flang/test/Semantics/numeric_storage_size.f90
@@ -1,4 +1,7 @@
 ! RUN: %flang_fc1 -fdebug-unparse %s 2>&1 | FileCheck %s --check-prefix=CHECK
+! RUN: %flang_fc1 -fdebug-unparse -fdefault-integer-4 %s 2>&1 | FileCheck %s --check-prefix=CHECK-I4
+! RUN: %flang_fc1 -fdebug-unparse %s -fdefault-real-4 2>&1 | FileCheck %s --check-prefix=CHECK-R4
+! RUN: %flang_fc1 -fdebug-unparse %s -fdefault-integer-4 -fdefault-real-4  2>&1 | FileCheck %s --check-prefix=CHECK-I4-R4
 ! RUN: %flang_fc1 -fdebug-unparse -fdefault-integer-8 %s 2>&1 | FileCheck %s --check-prefix=CHECK-I8
 ! RUN: %flang_fc1 -fdebug-unparse %s -fdefault-real-8 2>&1 | FileCheck %s --check-prefix=CHECK-R8
 ! RUN: %flang_fc1 -fdebug-unparse %s -fdefault-integer-8 -fdefault-real-8  2>&1 | FileCheck %s --check-prefix=CHECK-I8-R8
@@ -7,6 +10,9 @@
 
 !CHECK-NOT: warning
 !CHECK: nss = 32_4
+!CHECK-I4: nss = 32_4
+!CHECK-R4: nss = 32_4
+!CHECK-I4-R4: nss = 32_4
 !CHECK-I8: warning: NUMERIC_STORAGE_SIZE from ISO_FORTRAN_ENV is not well-defined when default INTEGER and REAL are not consistent due to compiler options
 !CHECK-I8: nss = 32_4
 !CHECK-R8: warning: NUMERIC_STORAGE_SIZE from ISO_FORTRAN_ENV is not well-defined when default INTEGER and REAL are not consistent due to compiler options
@@ -15,24 +21,36 @@
 integer, parameter :: nss = numeric_storage_size
 
 !CHECK: iss = 32_4
+!CHECK-I4: iss = 32_4
+!CHECK-R4: iss = 32_4
+!CHECK-I4-R4: iss = 32_4
 !CHECK-I8: iss = 64_8
 !CHECK-R8: iss = 32_4
 !CHECK-I8-R8: iss = 64_8
 integer, parameter :: iss = storage_size(1)
 
 !CHECK: rss = 32_4
+!CHECK-I4: rss = 32_4
+!CHECK-R4: rss = 32_4
+!CHECK-I4-R4: rss = 32_4
 !CHECK-I8: rss = 32_8
 !CHECK-R8: rss = 64_4
 !CHECK-I8-R8: rss = 64_8
 integer, parameter :: rss = storage_size(1.)
 
 !CHECK: zss = 64_4
+!CHECK-I4: zss = 64_4
+!CHECK-R4: zss = 64_4
+!CHECK-I4-R4: zss = 64_4
 !CHECK-I8: zss = 64_8
 !CHECK-R8: zss = 128_4
 !CHECK-I8-R8: zss = 128_8
 integer, parameter :: zss = storage_size((1.,0.))
 
 !CHECK: lss = 32_4
+!CHECK-I4: lss = 32_4
+!CHECK-R4: lss = 32_4
+!CHECK-I4-R4: lss = 32_4
 !CHECK-I8: lss = 64_8
 !CHECK-R8: lss = 32_4
 !CHECK-I8-R8: lss = 64_8

@llvmbot
Copy link
Member

llvmbot commented Dec 15, 2025

@llvm/pr-subscribers-flang-driver

Author: Tarun Prabhu (tarunprabhu)

Changes

These options are supported by the Intel compiler. There are similar options in the IBM compiler as well. Each of the options can be provided more than once. In that case, the last occurence of -fdefault-real-* (respectively -fdefault-integer-*) is used if both -fdefault-real-4 and -fdefault-real-8 are specified. The fdefault.f90 test file was extensively modified. The handling of the option by the driver was removed since testing the handling of the options by -fc1 is sufficient.

Fixes #160252


Notes for reviewers:

This was discussed during the flang call and also in this RFC. There were no objections raised during either the call or in the RFC.


Full diff: https://github.com/llvm/llvm-project/pull/172323.diff

6 Files Affected:

  • (modified) clang/include/clang/Options/Options.td (+4)
  • (modified) clang/lib/Driver/ToolChains/Flang.cpp (+2)
  • (modified) flang/lib/Frontend/CompilerInvocation.cpp (+28-8)
  • (modified) flang/test/Driver/fdefault.f90 (+99-31)
  • (modified) flang/test/Driver/frontend-forwarding.f90 (+4)
  • (modified) flang/test/Semantics/numeric_storage_size.f90 (+18)
diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td
index 45c5322351a17..000608134202d 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -7344,6 +7344,10 @@ def fdefault_integer_8 : Flag<["-"],"fdefault-integer-8">, Group<f_Group>,
   HelpText<"Set the default integer and logical kind to an 8 byte wide type">;
 def fdefault_real_8 : Flag<["-"],"fdefault-real-8">, Group<f_Group>,
   HelpText<"Set the default real kind to an 8 byte wide type">;
+def fdefault_integer_4 : Flag<["-"],"fdefault-integer-4">, Group<f_Group>,
+  HelpText<"Set the default integer and logical kind to a 4 byte wide type">;
+def fdefault_real_4 : Flag<["-"],"fdefault-real-4">, Group<f_Group>,
+  HelpText<"Set the default real kind to a 4 byte wide type">;
 def fdisable_real_3 : Flag<["-"],"fdisable-real-3">, Group<f_Group>,
    HelpText<"Disable real(KIND=3) from TargetCharacteristics">, Flags<[HelpHidden]>;
 def fdisable_real_10 : Flag<["-"],"fdisable-real-10">, Group<f_Group>,
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp
index 2f5e93d139858..128a4beaceeb9 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -51,6 +51,8 @@ void Flang::addFortranDialectOptions(const ArgList &Args,
                             options::OPT_fxor_operator,
                             options::OPT_fno_xor_operator,
                             options::OPT_falternative_parameter_statement,
+                            options::OPT_fdefault_integer_4,
+                            options::OPT_fdefault_real_4,
                             options::OPT_fdefault_real_8,
                             options::OPT_fdefault_integer_8,
                             options::OPT_fdefault_double_8,
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index b6c4e6303cdac..dd25cdc0e5707 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -1086,15 +1086,35 @@ static bool parseDialectArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
   }
 
   // -fdefault* family
-  if (args.hasArg(clang::options::OPT_fdefault_real_8)) {
-    res.getDefaultKinds().set_defaultRealKind(8);
-    res.getDefaultKinds().set_doublePrecisionKind(16);
+  if (const llvm::opt::Arg *arg =
+          args.getLastArg(clang::options::OPT_fdefault_real_8,
+                          clang::options::OPT_fdefault_real_4)) {
+    const llvm::opt::Option &opt = arg->getOption();
+    if (opt.matches(clang::options::OPT_fdefault_real_8)) {
+      res.getDefaultKinds().set_defaultRealKind(8);
+      res.getDefaultKinds().set_doublePrecisionKind(16);
+    } else if (opt.matches(clang::options::OPT_fdefault_real_4)) {
+      res.getDefaultKinds().set_defaultRealKind(4);
+      res.getDefaultKinds().set_doublePrecisionKind(8);
+    }
   }
-  if (args.hasArg(clang::options::OPT_fdefault_integer_8)) {
-    res.getDefaultKinds().set_defaultIntegerKind(8);
-    res.getDefaultKinds().set_subscriptIntegerKind(8);
-    res.getDefaultKinds().set_sizeIntegerKind(8);
-    res.getDefaultKinds().set_defaultLogicalKind(8);
+  if (const llvm::opt::Arg *arg =
+          args.getLastArg(clang::options::OPT_fdefault_integer_8,
+                          clang::options::OPT_fdefault_integer_4)) {
+    const llvm::opt::Option &opt = arg->getOption();
+    if (opt.matches(clang::options::OPT_fdefault_integer_8)) {
+      res.getDefaultKinds().set_defaultIntegerKind(8);
+      res.getDefaultKinds().set_subscriptIntegerKind(8);
+      res.getDefaultKinds().set_sizeIntegerKind(8);
+      res.getDefaultKinds().set_defaultLogicalKind(8);
+    } else if (opt.matches(clang::options::OPT_fdefault_integer_4)) {
+      // Note that the subscript integer kind is set to 8 here. If a
+      // default-integer-kind is not provided, it is also set to 8.
+      res.getDefaultKinds().set_defaultIntegerKind(4);
+      res.getDefaultKinds().set_subscriptIntegerKind(8);
+      res.getDefaultKinds().set_sizeIntegerKind(4);
+      res.getDefaultKinds().set_defaultLogicalKind(4);
+    }
   }
   if (args.hasArg(clang::options::OPT_fdefault_double_8)) {
     if (!args.hasArg(clang::options::OPT_fdefault_real_8)) {
diff --git a/flang/test/Driver/fdefault.f90 b/flang/test/Driver/fdefault.f90
index 7ce45b763a240..b879cd56157ed 100644
--- a/flang/test/Driver/fdefault.f90
+++ b/flang/test/Driver/fdefault.f90
@@ -1,46 +1,114 @@
 ! Ensure argument -fdefault* work as expected.
 ! TODO: Add checks when actual codegen is possible for this family
-
-!--------------------------
-! FLANG DRIVER (flang)
-!--------------------------
-! RUN: rm -rf %t/dir-flang  && mkdir -p %t/dir-flang && %flang -fsyntax-only -module-dir %t/dir-flang %s  2>&1
-! RUN: cat %t/dir-flang/m.mod | FileCheck %s --check-prefix=NOOPTION
-! RUN: rm -rf %t/dir-flang  && mkdir -p %t/dir-flang && %flang -fsyntax-only -fdefault-real-8 -module-dir %t/dir-flang %s  2>&1
-! RUN: cat %t/dir-flang/m.mod | FileCheck %s --check-prefix=REAL8
-! RUN: rm -rf %t/dir-flang  && mkdir -p %t/dir-flang && %flang -fsyntax-only -fdefault-real-8 -fdefault-double-8 -module-dir %t/dir-flang %s  2>&1
-! RUN: cat %t/dir-flang/m.mod | FileCheck %s --check-prefix=DOUBLE8
-! RUN: not %flang -fsyntax-only -fdefault-double-8 %s  2>&1 | FileCheck %s --check-prefix=ERROR
-
-!-----------------------------------------
-! FRONTEND FLANG DRIVER (flang -fc1)
-!-----------------------------------------
-! RUN: rm -rf %t/dir-flang  && mkdir -p %t/dir-flang && %flang_fc1 -fsyntax-only -module-dir %t/dir-flang %s  2>&1
-! RUN: cat %t/dir-flang/m.mod | FileCheck %s --check-prefix=NOOPTION
-! RUN: rm -rf %t/dir-flang  && mkdir -p %t/dir-flang && %flang_fc1 -fsyntax-only -fdefault-real-8 -module-dir %t/dir-flang %s  2>&1
-! RUN: cat %t/dir-flang/m.mod | FileCheck %s --check-prefix=REAL8
-! RUN: rm -rf %t/dir-flang  && mkdir -p %t/dir-flang && %flang_fc1 -fsyntax-only -fdefault-real-8 -fdefault-double-8 -module-dir %t/dir-flang %s  2>&1
-! RUN: cat %t/dir-flang/m.mod | FileCheck %s --check-prefix=DOUBLE8
-! RUN: not %flang_fc1 -fsyntax-only -fdefault-double-8 %s  2>&1 | FileCheck %s --check-prefix=ERROR
-
-! NOOPTION: integer(4),parameter::real_kind=4_4
+!
+! RUN: rm -rf %t && mkdir -p %t && \
+! RUN:    %flang_fc1 -fsyntax-only -module-dir %t %s
+! RUN: cat %t/m.mod | FileCheck %s --check-prefix=NOOPTION
+!
+! RUN: rm -rf %t && mkdir -p %t && \
+! RUN:   %flang_fc1 -fsyntax-only -fdefault-integer-4 -module-dir %t %s
+! RUN: cat %t/m.mod | FileCheck %s --check-prefix=INTEGER4
+!
+! RUN: rm -rf %t && mkdir -p %t && \
+! RUN:   %flang_fc1 -fsyntax-only -fdefault-real-4 -module-dir %t %s
+! RUN: cat %t/m.mod | FileCheck %s --check-prefix=REAL4
+!
+! RUN: rm -rf %t && mkdir -p %t && \
+! RUN:   %flang_fc1 -fsyntax-only -fdefault-integer-4 -fdefault-real-4 \
+! RUN:       -module-dir %t %s
+! RUN: cat %t/m.mod | FileCheck %s --check-prefix=BOTH4
+!
+! RUN: rm -rf %t && mkdir -p %t && \
+! RUN:   %flang_fc1 -fsyntax-only -fdefault-integer-8 -module-dir %t %s
+! RUN: cat %t/m.mod | FileCheck %s --check-prefix=INTEGER8
+!
+! RUN: rm -rf %t && mkdir -p %t && \
+! RUN:   %flang -fsyntax-only -fdefault-real-8 -module-dir %t %s
+! RUN: cat %t/m.mod | FileCheck %s --check-prefix=REAL8
+!
+! RUN: rm -rf %t && mkdir -p %t && \
+! RUN:   %flang_fc1 -fsyntax-only -fdefault-integer-8 -fdefault-real-8 \
+! RUN:       -module-dir %t %s
+! RUN: cat %t/m.mod | FileCheck %s --check-prefix=BOTH8
+!
+! RUN: rm -rf %t && mkdir -p %t && \
+! RUN:   %flang_fc1 -fsyntax-only -fdefault-real-8 -fdefault-double-8 \
+! RUN:       -module-dir %t %s
+! RUN: cat %t/m.mod | FileCheck %s --check-prefix=DOUBLE8
+!
+! RUN: not %flang_fc1 -fsyntax-only -fdefault-double-8 %s 2>&1 \
+! RUN:     | FileCheck %s --check-prefix=ERROR
+!
+! The last occurrence of -fdefault-* "wins"
+!
+! RUN: rm -rf %t && mkdir -p %t && \
+! RUN:   %flang_fc1 -fsyntax-only -fdefault-integer-4 -fdefault-integer-8 \
+! RUN:       -module-dir %t %s
+! RUN: cat %t/m.mod | FileCheck %s --check-prefix=INTEGER8
+!
+! RUN: rm -rf %t && mkdir -p %t && \
+! RUN:   %flang_fc1 -fsyntax-only -fdefault-integer-8 -fdefault-integer-4 \
+! RUN:       -module-dir %t %s
+! RUN: cat %t/m.mod | FileCheck %s --check-prefix=INTEGER4
+!
+! RUN: rm -rf %t && mkdir -p %t && \
+! RUN:   %flang_fc1 -fsyntax-only -fdefault-real-4 -fdefault-real-8 \
+! RUN:       -module-dir %t %s
+! RUN: cat %t/m.mod | FileCheck %s --check-prefix=REAL8
+!
+! RUN: rm -rf %t && mkdir -p %t && \
+! RUN:   %flang_fc1 -fsyntax-only -fdefault-real-8 -fdefault-real-4 \
+! RUN:       -module-dir %t %s
+! RUN: cat %t/m.mod | FileCheck %s --check-prefix=REAL4
+!
+! NOOPTION: integer(4),parameter::integer_kind=4_4
 ! NOOPTION-NEXT: intrinsic::kind
+! NOOPTION-NEXT: integer(4),parameter::real_kind=4_4
 ! NOOPTION-NEXT: integer(4),parameter::double_kind=8_4
-
-! REAL8: integer(4),parameter::real_kind=8_4
+!
+! INTEGER4: integer(4),parameter::integer_kind=4_4
+! INTEGER4-NEXT: intrinsic::kind
+! INTEGER4-NEXT: integer(4),parameter::real_kind=4_4
+! INTEGER4-NEXT: integer(4),parameter::double_kind=8_4
+!
+! REAL4: integer(4),parameter::integer_kind=4_4
+! REAL4-NEXT: intrinsic::kind
+! REAL4-NEXT: integer(4),parameter::real_kind=4_4
+! REAL4-NEXT: integer(4),parameter::double_kind=8_4
+!
+! BOTH4: integer(4),parameter::integer_kind=4_4
+! BOTH4-NEXT: intrinsic::kind
+! BOTH4-NEXT: integer(4),parameter::real_kind=4_4
+! BOTH4-NEXT: integer(4),parameter::double_kind=8_4
+!
+! INTEGER8: integer(8),parameter::integer_kind=8_8
+! INTEGER8-NEXT: intrinsic::kind
+! INTEGER8-NEXT: integer(8),parameter::real_kind=4_8
+! INTEGER8-NEXT: integer(8),parameter::double_kind=8_8
+!
+! REAL8: integer(4),parameter::integer_kind=4_4
 ! REAL8-NEXT: intrinsic::kind
+! REAL8-NEXT: integer(4),parameter::real_kind=8_4
 ! REAL8-NEXT: integer(4),parameter::double_kind=16_4
-
-! DOUBLE8: integer(4),parameter::real_kind=8_4
+!
+! BOTH8: integer(8),parameter::integer_kind=8_8
+! BOTH8-NEXT: intrinsic::kind
+! BOTH8-NEXT: integer(8),parameter::real_kind=8_8
+! BOTH8-NEXT: integer(8),parameter::double_kind=16_8
+!
+! DOUBLE8: integer(4),parameter::integer_kind=4_4
 ! DOUBLE8-NEXT: intrinsic::kind
+! DOUBLE8-NEXT: integer(4),parameter::real_kind=8_4
 ! DOUBLE8-NEXT: integer(4),parameter::double_kind=8_4
-
+!
 ! ERROR: Use of `-fdefault-double-8` requires `-fdefault-real-8`
 
 module m
   implicit none
+  integer :: i
   real :: x
   double precision :: y
-  integer, parameter :: real_kind = kind(x)            !-fdefault-real-8
-  integer, parameter :: double_kind = kind(y)          !-fdefault-double-8
+  integer, parameter :: integer_kind = kind(i)         !-fdefault-integer-*
+  integer, parameter :: real_kind = kind(x)            !-fdefault-real-*
+  integer, parameter :: double_kind = kind(y)          !-fdefault-double-*
 end
diff --git a/flang/test/Driver/frontend-forwarding.f90 b/flang/test/Driver/frontend-forwarding.f90
index 952937168c95d..976454f8f2181 100644
--- a/flang/test/Driver/frontend-forwarding.f90
+++ b/flang/test/Driver/frontend-forwarding.f90
@@ -3,6 +3,8 @@
 
 ! RUN: %flang -fsyntax-only -### %s -o %t 2>&1 \
 ! RUN:     -finput-charset=utf-8 \
+! RUN:     -fdefault-integer-4 \
+! RUN:     -fdefault-real-4 \
 ! RUN:     -fdefault-double-8 \
 ! RUN:     -fdefault-integer-8 \
 ! RUN:     -fdefault-real-8 \
@@ -36,6 +38,8 @@
 
 ! CHECK: "-P"
 ! CHECK: "-finput-charset=utf-8"
+! CHECK: "-fdefault-integer-4"
+! CHECK: "-fdefault-real-4"
 ! CHECK: "-fdefault-double-8"
 ! CHECK: "-fdefault-integer-8"
 ! CHECK: "-fdefault-real-8"
diff --git a/flang/test/Semantics/numeric_storage_size.f90 b/flang/test/Semantics/numeric_storage_size.f90
index 720297c0feb30..ee11f3b15d5bf 100644
--- a/flang/test/Semantics/numeric_storage_size.f90
+++ b/flang/test/Semantics/numeric_storage_size.f90
@@ -1,4 +1,7 @@
 ! RUN: %flang_fc1 -fdebug-unparse %s 2>&1 | FileCheck %s --check-prefix=CHECK
+! RUN: %flang_fc1 -fdebug-unparse -fdefault-integer-4 %s 2>&1 | FileCheck %s --check-prefix=CHECK-I4
+! RUN: %flang_fc1 -fdebug-unparse %s -fdefault-real-4 2>&1 | FileCheck %s --check-prefix=CHECK-R4
+! RUN: %flang_fc1 -fdebug-unparse %s -fdefault-integer-4 -fdefault-real-4  2>&1 | FileCheck %s --check-prefix=CHECK-I4-R4
 ! RUN: %flang_fc1 -fdebug-unparse -fdefault-integer-8 %s 2>&1 | FileCheck %s --check-prefix=CHECK-I8
 ! RUN: %flang_fc1 -fdebug-unparse %s -fdefault-real-8 2>&1 | FileCheck %s --check-prefix=CHECK-R8
 ! RUN: %flang_fc1 -fdebug-unparse %s -fdefault-integer-8 -fdefault-real-8  2>&1 | FileCheck %s --check-prefix=CHECK-I8-R8
@@ -7,6 +10,9 @@
 
 !CHECK-NOT: warning
 !CHECK: nss = 32_4
+!CHECK-I4: nss = 32_4
+!CHECK-R4: nss = 32_4
+!CHECK-I4-R4: nss = 32_4
 !CHECK-I8: warning: NUMERIC_STORAGE_SIZE from ISO_FORTRAN_ENV is not well-defined when default INTEGER and REAL are not consistent due to compiler options
 !CHECK-I8: nss = 32_4
 !CHECK-R8: warning: NUMERIC_STORAGE_SIZE from ISO_FORTRAN_ENV is not well-defined when default INTEGER and REAL are not consistent due to compiler options
@@ -15,24 +21,36 @@
 integer, parameter :: nss = numeric_storage_size
 
 !CHECK: iss = 32_4
+!CHECK-I4: iss = 32_4
+!CHECK-R4: iss = 32_4
+!CHECK-I4-R4: iss = 32_4
 !CHECK-I8: iss = 64_8
 !CHECK-R8: iss = 32_4
 !CHECK-I8-R8: iss = 64_8
 integer, parameter :: iss = storage_size(1)
 
 !CHECK: rss = 32_4
+!CHECK-I4: rss = 32_4
+!CHECK-R4: rss = 32_4
+!CHECK-I4-R4: rss = 32_4
 !CHECK-I8: rss = 32_8
 !CHECK-R8: rss = 64_4
 !CHECK-I8-R8: rss = 64_8
 integer, parameter :: rss = storage_size(1.)
 
 !CHECK: zss = 64_4
+!CHECK-I4: zss = 64_4
+!CHECK-R4: zss = 64_4
+!CHECK-I4-R4: zss = 64_4
 !CHECK-I8: zss = 64_8
 !CHECK-R8: zss = 128_4
 !CHECK-I8-R8: zss = 128_8
 integer, parameter :: zss = storage_size((1.,0.))
 
 !CHECK: lss = 32_4
+!CHECK-I4: lss = 32_4
+!CHECK-R4: lss = 32_4
+!CHECK-I4-R4: lss = 32_4
 !CHECK-I8: lss = 64_8
 !CHECK-R8: lss = 32_4
 !CHECK-I8-R8: lss = 64_8

Copy link
Contributor

@jeanPerier jeanPerier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, thanks Tarun.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' flang:driver flang:semantics flang Flang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[flang] -fdefault-integer-4 is not implemented

3 participants