diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td index c38bdd06057a2..0a32408cb0e46 100644 --- a/clang/include/clang/Options/Options.td +++ b/clang/include/clang/Options/Options.td @@ -7348,6 +7348,10 @@ def fdefault_integer_8 : Flag<["-"],"fdefault-integer-8">, Group, HelpText<"Set the default integer and logical kind to an 8 byte wide type">; def fdefault_real_8 : Flag<["-"],"fdefault-real-8">, Group, HelpText<"Set the default real kind to an 8 byte wide type">; +def fdefault_integer_4 : Flag<["-"],"fdefault-integer-4">, Group, + HelpText<"Set the default integer and logical kind to a 4 byte wide type">; +def fdefault_real_4 : Flag<["-"],"fdefault-real-4">, Group, + HelpText<"Set the default real kind to a 4 byte wide type">; def fdisable_real_3 : Flag<["-"],"fdisable-real-3">, Group, HelpText<"Disable real(KIND=3) from TargetCharacteristics">, Flags<[HelpHidden]>; def fdisable_real_10 : Flag<["-"],"fdisable-real-10">, 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 f47d8010bc233..e4cb0b6835a75 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 \ @@ -35,6 +37,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