8244146: javac changes for JEP 306
8266399: Core libs update for JEP 306 Reviewed-by: sadayapalam, bpb, naoto
This commit is contained in:
parent
c2c0208dfd
commit
0ae4ceb413
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -120,7 +120,7 @@ class FdLibm {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public static strictfp double compute(double x) {
|
||||
public static double compute(double x) {
|
||||
double t = 0.0;
|
||||
double sign;
|
||||
|
||||
@ -203,7 +203,7 @@ class FdLibm {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public static strictfp double compute(double x, double y) {
|
||||
public static double compute(double x, double y) {
|
||||
double a = Math.abs(x);
|
||||
double b = Math.abs(y);
|
||||
|
||||
@ -343,7 +343,7 @@ class FdLibm {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public static strictfp double compute(final double x, final double y) {
|
||||
public static double compute(final double x, final double y) {
|
||||
double z;
|
||||
double r, s, t, u, v, w;
|
||||
int i, j, k, n;
|
||||
@ -680,8 +680,7 @@ class FdLibm {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
// should be able to forgo strictfp due to controlled over/underflow
|
||||
public static strictfp double compute(double x) {
|
||||
public static double compute(double x) {
|
||||
double y;
|
||||
double hi = 0.0;
|
||||
double lo = 0.0;
|
||||
|
@ -86,7 +86,6 @@ import jdk.internal.vm.annotation.IntrinsicCandidate;
|
||||
* @author Joseph D. Darcy
|
||||
* @since 1.3
|
||||
*/
|
||||
|
||||
public final class StrictMath {
|
||||
|
||||
/**
|
||||
@ -207,10 +206,8 @@ public final class StrictMath {
|
||||
* @return the measurement of the angle {@code angdeg}
|
||||
* in radians.
|
||||
*/
|
||||
public static strictfp double toRadians(double angdeg) {
|
||||
// Do not delegate to Math.toRadians(angdeg) because
|
||||
// this method has the strictfp modifier.
|
||||
return angdeg * DEGREES_TO_RADIANS;
|
||||
public static double toRadians(double angdeg) {
|
||||
return Math.toRadians(angdeg);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -224,10 +221,8 @@ public final class StrictMath {
|
||||
* @return the measurement of the angle {@code angrad}
|
||||
* in degrees.
|
||||
*/
|
||||
public static strictfp double toDegrees(double angrad) {
|
||||
// Do not delegate to Math.toDegrees(angrad) because
|
||||
// this method has the strictfp modifier.
|
||||
return angrad * RADIANS_TO_DEGREES;
|
||||
public static double toDegrees(double angrad) {
|
||||
return Math.toDegrees(angrad);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -118,6 +118,9 @@ public class Lint
|
||||
if (source.compareTo(Source.JDK9) >= 0) {
|
||||
values.add(LintCategory.DEP_ANN);
|
||||
}
|
||||
if (Source.Feature.REDUNDANT_STRICTFP.allowedInSource(source)) {
|
||||
values.add(LintCategory.STRICTFP);
|
||||
}
|
||||
values.add(LintCategory.REQUIRES_TRANSITIVE_AUTOMATIC);
|
||||
values.add(LintCategory.OPENS);
|
||||
values.add(LintCategory.MODULE);
|
||||
@ -283,6 +286,11 @@ public class Lint
|
||||
*/
|
||||
STATIC("static"),
|
||||
|
||||
/**
|
||||
* Warn about unnecessary uses of the strictfp modifier
|
||||
*/
|
||||
STRICTFP("strictfp"),
|
||||
|
||||
/**
|
||||
* Warn about synchronization attempts on instances of @ValueBased classes.
|
||||
*/
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -224,6 +224,7 @@ public enum Source {
|
||||
REIFIABLE_TYPES_INSTANCEOF(JDK16, Fragments.FeatureReifiableTypesInstanceof, DiagKind.PLURAL),
|
||||
RECORDS(JDK16, Fragments.FeatureRecords, DiagKind.PLURAL),
|
||||
SEALED_CLASSES(JDK17, Fragments.FeatureSealedClasses, DiagKind.PLURAL),
|
||||
REDUNDANT_STRICTFP(JDK17),
|
||||
;
|
||||
|
||||
enum DiagKind {
|
||||
|
@ -1211,6 +1211,9 @@ public class Check {
|
||||
} else {
|
||||
mask = MethodFlags;
|
||||
}
|
||||
if ((flags & STRICTFP) != 0) {
|
||||
warnOnExplicitStrictfp(pos);
|
||||
}
|
||||
// Imply STRICTFP if owner has STRICTFP set.
|
||||
if (((flags|implicit) & Flags.ABSTRACT) == 0 ||
|
||||
((flags) & Flags.DEFAULT) != 0)
|
||||
@ -1252,6 +1255,9 @@ public class Check {
|
||||
mask &= ~ABSTRACT;
|
||||
implicit |= FINAL;
|
||||
}
|
||||
if ((flags & STRICTFP) != 0) {
|
||||
warnOnExplicitStrictfp(pos);
|
||||
}
|
||||
// Imply STRICTFP if owner has STRICTFP set.
|
||||
implicit |= sym.owner.flags_field & STRICTFP;
|
||||
break;
|
||||
@ -1314,6 +1320,19 @@ public class Check {
|
||||
return flags & (mask | ~ExtendedStandardFlags) | implicit;
|
||||
}
|
||||
|
||||
private void warnOnExplicitStrictfp(DiagnosticPosition pos) {
|
||||
DiagnosticPosition prevLintPos = deferredLintHandler.setPos(pos);
|
||||
try {
|
||||
deferredLintHandler.report(() -> {
|
||||
if (lint.isEnabled(LintCategory.STRICTFP)) {
|
||||
log.warning(LintCategory.STRICTFP,
|
||||
pos, Warnings.Strictfp); }
|
||||
});
|
||||
} finally {
|
||||
deferredLintHandler.setPos(prevLintPos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Determine if this enum should be implicitly final.
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -41,6 +41,7 @@ import static com.sun.tools.javac.jvm.ByteCodes.*;
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
@SuppressWarnings("strictfp")
|
||||
strictfp class ConstFold {
|
||||
protected static final Context.Key<ConstFold> constFoldKey = new Context.Key<>();
|
||||
|
||||
|
@ -40,6 +40,7 @@ import javax.tools.JavaFileObject;
|
||||
import com.sun.tools.javac.code.*;
|
||||
import com.sun.tools.javac.code.Attribute.RetentionPolicy;
|
||||
import com.sun.tools.javac.code.Directive.*;
|
||||
import com.sun.tools.javac.code.Source.Feature;
|
||||
import com.sun.tools.javac.code.Symbol.*;
|
||||
import com.sun.tools.javac.code.Type.*;
|
||||
import com.sun.tools.javac.code.Types.SignatureGenerator.InvalidSignatureException;
|
||||
@ -1697,6 +1698,10 @@ public class ClassWriter extends ClassFile {
|
||||
int adjustFlags(final long flags) {
|
||||
int result = (int)flags;
|
||||
|
||||
// Elide strictfp bit in class files
|
||||
if (target.obsoleteAccStrict())
|
||||
result &= ~STRICTFP;
|
||||
|
||||
if ((flags & BRIDGE) != 0)
|
||||
result |= ACC_BRIDGE;
|
||||
if ((flags & VARARGS) != 0)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -194,4 +194,10 @@ public enum Target {
|
||||
public boolean hasSealedClasses() {
|
||||
return compareTo(JDK1_15) >= 0;
|
||||
}
|
||||
|
||||
/** Is the ACC_STRICT bit redundant and obsolete
|
||||
*/
|
||||
public boolean obsoleteAccStrict() {
|
||||
return compareTo(JDK1_17) >= 0;
|
||||
}
|
||||
}
|
||||
|
@ -564,10 +564,10 @@ compiler.err.foreach.not.applicable.to.type=\
|
||||
found: {0}
|
||||
|
||||
compiler.err.fp.number.too.large=\
|
||||
floating point number too large
|
||||
floating-point number too large
|
||||
|
||||
compiler.err.fp.number.too.small=\
|
||||
floating point number too small
|
||||
floating-point number too small
|
||||
|
||||
compiler.err.generic.array.creation=\
|
||||
generic array creation
|
||||
@ -785,7 +785,7 @@ compiler.err.limit.string.overflow=\
|
||||
UTF8 representation for string \"{0}...\" is too long for the constant pool
|
||||
|
||||
compiler.err.malformed.fp.lit=\
|
||||
malformed floating point literal
|
||||
malformed floating-point literal
|
||||
|
||||
compiler.err.method.does.not.override.superclass=\
|
||||
method does not override or implement a method from a supertype
|
||||
@ -1764,6 +1764,9 @@ compiler.warn.dir.path.element.not.directory=\
|
||||
compiler.warn.missing-explicit-ctor=\
|
||||
class {0} in exported package {1} declares no explicit constructors, thereby exposing a default constructor to clients of module {2}
|
||||
|
||||
compiler.warn.strictfp=\
|
||||
as of release 17, all floating-point expressions are evaluated strictly and ''strictfp'' is not required
|
||||
|
||||
compiler.warn.finally.cannot.complete=\
|
||||
finally clause cannot complete normally
|
||||
|
||||
|
@ -246,6 +246,9 @@ javac.opt.Xlint.desc.serial=\
|
||||
javac.opt.Xlint.desc.static=\
|
||||
Warn about accessing a static member using an instance.
|
||||
|
||||
javac.opt.Xlint.desc.strictfp=\
|
||||
Warn about unnecessary use of the strictfp modifier.
|
||||
|
||||
javac.opt.Xlint.desc.text-blocks=\
|
||||
Warn about inconsistent white space characters in text block indentation.
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -167,7 +167,7 @@ class TaskFactory {
|
||||
List<String> allOptions = new ArrayList<>();
|
||||
|
||||
allOptions.add("--should-stop=at=FLOW");
|
||||
allOptions.add("-Xlint:unchecked");
|
||||
allOptions.add("-Xlint:unchecked,-strictfp");
|
||||
allOptions.add("-proc:none");
|
||||
allOptions.addAll(extraArgs);
|
||||
|
||||
@ -184,7 +184,7 @@ class TaskFactory {
|
||||
|
||||
return runTask(wraps.stream(),
|
||||
sh,
|
||||
List.of("-Xlint:unchecked", "-proc:none", "-parameters"),
|
||||
List.of("-Xlint:unchecked,-strictfp", "-proc:none", "-parameters"),
|
||||
(jti, diagnostics) -> new CompileTask(sh, jti, diagnostics),
|
||||
worker);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2004, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -179,10 +179,10 @@ interface TestInterface1 {
|
||||
default <A> A bar(){return null;}
|
||||
|
||||
@ExpectedString(
|
||||
"public default strictfp double TestInterface1.quux()")
|
||||
"public default double TestInterface1.quux()")
|
||||
@ExpectedGenericString(
|
||||
"public default strictfp double TestInterface1.quux()")
|
||||
strictfp default double quux(){return 1.0;}
|
||||
"public default double TestInterface1.quux()")
|
||||
default double quux(){return 1.0;}
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -26,6 +26,7 @@
|
||||
* @bug 7166455
|
||||
* @summary javac doesn't set ACC_STRICT bit on <clinit> for strictfp class
|
||||
* @modules jdk.jdeps/com.sun.tools.classfile
|
||||
* @compile -source 16 -target 16 CheckACC_STRICTFlagOnclinitTest.java
|
||||
* @run main CheckACC_STRICTFlagOnclinitTest
|
||||
*/
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -81,7 +81,8 @@ public class CheckACC_STRICTFlagOnPkgAccessClassTest {
|
||||
}
|
||||
|
||||
private void compile(JavaCompiler comp) {
|
||||
JavacTask ct = (JavacTask)comp.getTask(null, null, null, null, null,
|
||||
JavacTask ct = (JavacTask)comp.getTask(null, null, null,
|
||||
List.of("--release", "16"), null,
|
||||
Arrays.asList(source));
|
||||
try {
|
||||
if (!ct.call()) {
|
||||
|
@ -1,10 +1,11 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 4153038 4785453
|
||||
* @bug 4153038 4785453 8244146
|
||||
* @summary strictfp may not be used with constructors
|
||||
* @author David Stoutamire (dps)
|
||||
*
|
||||
* @compile/fail/ref=BadConstructorModifiers.out -XDrawDiagnostics BadConstructorModifiers.java
|
||||
* @compile/fail/ref=BadConstructorModifiers.out -XDrawDiagnostics --release 16 BadConstructorModifiers.java
|
||||
* @compile/fail/ref=BadConstructorModifiers.out -XDrawDiagnostics -Xlint:-strictfp BadConstructorModifiers.java
|
||||
*/
|
||||
|
||||
public class BadConstructorModifiers {
|
||||
|
@ -1,2 +1,2 @@
|
||||
BadConstructorModifiers.java:12:14: compiler.err.mod.not.allowed.here: strictfp
|
||||
BadConstructorModifiers.java:13:14: compiler.err.mod.not.allowed.here: strictfp
|
||||
1 error
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2006, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -49,7 +49,7 @@ public abstract class T6397044 {
|
||||
try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) {
|
||||
Iterable<? extends JavaFileObject> files
|
||||
= fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(srcDir, self + ".java")));
|
||||
JavacTask task = tool.getTask(null, fm, null, null, null, files);
|
||||
JavacTask task = tool.getTask(null, fm, null, List.of("--release", "16"), null, files);
|
||||
Iterable<? extends CompilationUnitTree> trees = task.parse();
|
||||
Checker checker = new Checker();
|
||||
for (CompilationUnitTree tree: trees)
|
||||
|
@ -1,8 +1,9 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8028428
|
||||
* @bug 8028428 8244146
|
||||
* @summary Test that only 'public' and 'abstract' elements compile
|
||||
* @compile/fail/ref=AnnotationTypeElementModifiers.out -XDrawDiagnostics AnnotationTypeElementModifiers.java
|
||||
* @compile/fail/ref=AnnotationTypeElementModifiers.out -XDrawDiagnostics --release 16 AnnotationTypeElementModifiers.java
|
||||
* @compile/fail/ref=AnnotationTypeElementModifiers.out -XDrawDiagnostics -Xlint:-strictfp AnnotationTypeElementModifiers.java
|
||||
*/
|
||||
|
||||
public @interface AnnotationTypeElementModifiers {
|
||||
|
@ -1,21 +1,21 @@
|
||||
AnnotationTypeElementModifiers.java:17:17: compiler.err.mod.not.allowed.here: private
|
||||
AnnotationTypeElementModifiers.java:18:17: compiler.err.mod.not.allowed.here: private
|
||||
AnnotationTypeElementModifiers.java:20:19: compiler.err.mod.not.allowed.here: protected
|
||||
AnnotationTypeElementModifiers.java:19:17: compiler.err.mod.not.allowed.here: private
|
||||
AnnotationTypeElementModifiers.java:21:19: compiler.err.mod.not.allowed.here: protected
|
||||
AnnotationTypeElementModifiers.java:23:16: compiler.err.mod.not.allowed.here: static
|
||||
AnnotationTypeElementModifiers.java:22:19: compiler.err.mod.not.allowed.here: protected
|
||||
AnnotationTypeElementModifiers.java:24:16: compiler.err.mod.not.allowed.here: static
|
||||
AnnotationTypeElementModifiers.java:26:15: compiler.err.mod.not.allowed.here: final
|
||||
AnnotationTypeElementModifiers.java:25:16: compiler.err.mod.not.allowed.here: static
|
||||
AnnotationTypeElementModifiers.java:27:15: compiler.err.mod.not.allowed.here: final
|
||||
AnnotationTypeElementModifiers.java:29:22: compiler.err.mod.not.allowed.here: synchronized
|
||||
AnnotationTypeElementModifiers.java:28:15: compiler.err.mod.not.allowed.here: final
|
||||
AnnotationTypeElementModifiers.java:30:22: compiler.err.mod.not.allowed.here: synchronized
|
||||
AnnotationTypeElementModifiers.java:32:18: compiler.err.mod.not.allowed.here: volatile
|
||||
AnnotationTypeElementModifiers.java:31:22: compiler.err.mod.not.allowed.here: synchronized
|
||||
AnnotationTypeElementModifiers.java:33:18: compiler.err.mod.not.allowed.here: volatile
|
||||
AnnotationTypeElementModifiers.java:35:19: compiler.err.mod.not.allowed.here: transient
|
||||
AnnotationTypeElementModifiers.java:34:18: compiler.err.mod.not.allowed.here: volatile
|
||||
AnnotationTypeElementModifiers.java:36:19: compiler.err.mod.not.allowed.here: transient
|
||||
AnnotationTypeElementModifiers.java:38:16: compiler.err.mod.not.allowed.here: native
|
||||
AnnotationTypeElementModifiers.java:37:19: compiler.err.mod.not.allowed.here: transient
|
||||
AnnotationTypeElementModifiers.java:39:16: compiler.err.mod.not.allowed.here: native
|
||||
AnnotationTypeElementModifiers.java:41:20: compiler.err.mod.not.allowed.here: strictfp
|
||||
AnnotationTypeElementModifiers.java:40:16: compiler.err.mod.not.allowed.here: native
|
||||
AnnotationTypeElementModifiers.java:42:20: compiler.err.mod.not.allowed.here: strictfp
|
||||
AnnotationTypeElementModifiers.java:44:17: compiler.err.mod.not.allowed.here: default
|
||||
AnnotationTypeElementModifiers.java:43:20: compiler.err.mod.not.allowed.here: strictfp
|
||||
AnnotationTypeElementModifiers.java:45:17: compiler.err.mod.not.allowed.here: default
|
||||
AnnotationTypeElementModifiers.java:46:17: compiler.err.mod.not.allowed.here: default
|
||||
20 errors
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -30,7 +30,7 @@
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.jdeps/com.sun.tools.javap
|
||||
* @build toolbox.ToolBox toolbox.JavapTask
|
||||
* @run compile -g NestedLambdasCastedTest.java
|
||||
* @run compile -source 16 -target 16 -g NestedLambdasCastedTest.java
|
||||
* @run main NestedLambdasCastedTest
|
||||
*/
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -26,6 +26,7 @@
|
||||
* @bug 8012723
|
||||
* @summary strictfp interface misses strictfp modifer on default method
|
||||
* @modules jdk.jdeps/com.sun.tools.classfile
|
||||
* @compile -source 16 -target 16 CheckACC_STRICTFlagOnDefaultMethodTest.java
|
||||
* @run main CheckACC_STRICTFlagOnDefaultMethodTest
|
||||
*/
|
||||
|
||||
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
// key: compiler.warn.strictfp
|
||||
// options: -Xlint:strictfp
|
||||
|
||||
strictfp class UnneededStrictfpWarning {
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -26,6 +26,8 @@
|
||||
* @bug 8046060
|
||||
* @summary Different results of floating point multiplication for lambda code block
|
||||
* @modules jdk.jdeps/com.sun.tools.classfile
|
||||
* @compile -source 16 -target 16 LambdaTestStrictFPFlag.java
|
||||
* @run main LambdaTestStrictFPFlag
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
|
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Enclosing class for several strictfp-using types and methods.
|
||||
*
|
||||
* In the JVM, the ACC_STRICT bit is only defined for
|
||||
* methods/constructors and *not* classes/interfaces. Therefore, for
|
||||
* the checking in this test, the @StrictfpInSource annotation is only
|
||||
* applied to methods/constructors.
|
||||
*/
|
||||
public class StrictfpHost {
|
||||
public strictfp interface StrictfpInterface {
|
||||
// Implicitly strictfp
|
||||
@StrictfpInSource
|
||||
default double foo() {return 42.0;}
|
||||
}
|
||||
|
||||
public strictfp class StrictfpClass {
|
||||
// Implicitly strictfp
|
||||
@StrictfpInSource
|
||||
public StrictfpClass() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
@StrictfpInSource
|
||||
public strictfp static void main(String... args) {
|
||||
return;
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.lang.annotation.*;
|
||||
import static java.lang.annotation.ElementType.*;
|
||||
import static java.lang.annotation.RetentionPolicy.*;
|
||||
|
||||
|
||||
/**
|
||||
* At the JVM level, the ACC_STRICT bit is only defined for
|
||||
* methods/constructors, unlike where strictfp can be applied in
|
||||
* sources.
|
||||
*/
|
||||
@Retention(RUNTIME)
|
||||
@Target({METHOD, CONSTRUCTOR})
|
||||
public @interface StrictfpInSource {}
|
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8244146
|
||||
* @summary Test test and class file retention of strictfp.
|
||||
* @compile --release 16 TestStrictfpRetention.java StrictfpInSource.java
|
||||
* @compile -processor TestStrictfpRetention --release 16 StrictfpHost.java
|
||||
* @compile/process -processor TestStrictfpRetention --release 16 -proc:only StrictfpHost
|
||||
* @compile -processor TestStrictfpRetention -proc:only StrictfpHost.java
|
||||
* @compile -processor TestStrictfpRetention -source 16 StrictfpHost.java
|
||||
* @compile/process -processor TestStrictfpRetention -AstrictfpNotExpected StrictfpHost
|
||||
*/
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import javax.annotation.processing.*;
|
||||
import javax.lang.model.SourceVersion;
|
||||
import static javax.lang.model.SourceVersion.*;
|
||||
import javax.lang.model.element.*;
|
||||
import javax.lang.model.util.*;
|
||||
import static javax.tools.Diagnostic.Kind.*;
|
||||
|
||||
import static javax.lang.model.element.Modifier.*;
|
||||
|
||||
/**
|
||||
* The StrictfpInSource annotation marks whether or not the element in
|
||||
* source was declared strictp in its source form. For release 16 (and
|
||||
* earlier releases), the strictfp-in-source status and
|
||||
* strictfp-in-class file status should generally match. (Per JLS,
|
||||
* some elements are implicitly strictfp).
|
||||
*
|
||||
* Under release 17 and later releases reflecting JEP 306, while
|
||||
* strictfp can be present in the source, it is *not* persisted to the
|
||||
* class file for methods/constructors where ACC_STRICT can be
|
||||
* applied. (The ACC_STRICT modifier is not defined for
|
||||
* classes/interfaces in the JVM.)
|
||||
*
|
||||
* This test checks that the strictfp modifier of the annotated
|
||||
* elements is as expected in the four combinations:
|
||||
*
|
||||
* (source, class file) X (--release 16, current release)
|
||||
*
|
||||
* As well as the mixed combination of -source 16 and current release
|
||||
* as the implicit target.
|
||||
*/
|
||||
@SupportedOptions("strictfpNotExpected")
|
||||
@SupportedAnnotationTypes("StrictfpInSource")
|
||||
public class TestStrictfpRetention extends AbstractProcessor {
|
||||
public boolean process(Set<? extends TypeElement> annotations,
|
||||
RoundEnvironment roundEnv) {
|
||||
if (!roundEnv.processingOver()) {
|
||||
boolean annotatedElementsFound = false;
|
||||
boolean strictfpExpected = !processingEnv.getOptions().containsKey("strictfpNotExpected");
|
||||
var messager = processingEnv.getMessager();
|
||||
|
||||
for (Element e: roundEnv.getElementsAnnotatedWith(StrictfpInSource.class)) {
|
||||
annotatedElementsFound = true;
|
||||
|
||||
boolean strictfpPresent = e.getModifiers().contains(STRICTFP);
|
||||
if (strictfpPresent != strictfpExpected) {
|
||||
messager.printMessage(ERROR, "Unexpected strictfp status: " + strictfpPresent + " " + e, e);
|
||||
}
|
||||
}
|
||||
|
||||
if (!annotatedElementsFound) {
|
||||
messager.printMessage(ERROR, "No annotated elements found");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SourceVersion getSupportedSourceVersion() {
|
||||
return SourceVersion.latest();
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -143,8 +143,8 @@ interface ProviderOfDefault {
|
||||
boolean process(Set<? extends TypeElement> annotations,
|
||||
RoundEnvironment roundEnv);
|
||||
|
||||
@IsDefault(value=true, expectedTextRegex="\\s*@IsDefault\\(.*\\)\\s*default strictfp void quux\\(\\);\\s*$")
|
||||
default strictfp void quux() {};
|
||||
@IsDefault(value=true, expectedTextRegex="\\s*@IsDefault\\(.*\\)\\s*default void quux\\(\\);\\s*$")
|
||||
default void quux() {};
|
||||
@IsDefault(false)
|
||||
static void statik() {}
|
||||
}
|
||||
|
@ -0,0 +1,262 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8244146
|
||||
* @summary Verify expected strictfp warnings are producted or not produced
|
||||
* @library /tools/lib
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* @build toolbox.ToolBox toolbox.JavacTask toolbox.TestRunner
|
||||
* @run main UnneededStrictfpWarningToolBox
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.util.EnumSet;
|
||||
import javax.tools.JavaFileManager;
|
||||
import javax.tools.JavaFileObject;
|
||||
import javax.tools.StandardLocation;
|
||||
import javax.tools.ToolProvider;
|
||||
import toolbox.JavacTask;
|
||||
import toolbox.Task;
|
||||
import toolbox.Task.Expect;
|
||||
import toolbox.TestRunner;
|
||||
import toolbox.ToolBox;
|
||||
|
||||
public class UnneededStrictfpWarningToolBox extends TestRunner {
|
||||
|
||||
private final ToolBox tb = new ToolBox();
|
||||
private final String fileSep = System.getProperty("file.separator");
|
||||
|
||||
public UnneededStrictfpWarningToolBox() {
|
||||
super(System.err);
|
||||
}
|
||||
|
||||
public static void main(String... args) throws Exception {
|
||||
new UnneededStrictfpWarningToolBox().runTests();
|
||||
}
|
||||
|
||||
private void checkLog(List<String> log, List<String> expected) {
|
||||
if (!expected.equals(log)) {
|
||||
throw new AssertionError("Unexpected output: " + log);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkEmptyLog(List<String> log) {
|
||||
checkLog(log, List.of(""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithAndWithOutLint(Path base) throws IOException {
|
||||
Path src = base.resolve("src");
|
||||
|
||||
tb.writeJavaFiles(src, UNNEEDED_STRICTFP_WARNING1_NO_SUPPRESSION);
|
||||
Path classes = base.resolve("classes");
|
||||
tb.createDirectories(classes);
|
||||
|
||||
List<String> log;
|
||||
|
||||
// Warning not enabled, no messages expected
|
||||
log = new JavacTask(tb)
|
||||
.options("--release", "16", "-Werror")
|
||||
.outdir(classes)
|
||||
.files(tb.findJavaFiles(src))
|
||||
.run(Expect.SUCCESS)
|
||||
.writeAll()
|
||||
.getOutputLines(Task.OutputKind.DIRECT);
|
||||
checkEmptyLog(log);
|
||||
|
||||
// Warning not enabled, no messages expected
|
||||
log = new JavacTask(tb)
|
||||
.options("-Xlint:-strictfp", "-Werror")
|
||||
.outdir(classes)
|
||||
.files(tb.findJavaFiles(src))
|
||||
.run(Expect.SUCCESS)
|
||||
.writeAll()
|
||||
.getOutputLines(Task.OutputKind.DIRECT);
|
||||
checkEmptyLog(log);
|
||||
|
||||
// Warning enabled, 5 messages expected
|
||||
log = new JavacTask(tb)
|
||||
.options("-XDrawDiagnostics")
|
||||
.outdir(classes)
|
||||
.files(tb.findJavaFiles(src))
|
||||
.run(Expect.SUCCESS)
|
||||
.writeAll()
|
||||
.getOutputLines(Task.OutputKind.DIRECT);
|
||||
|
||||
var expected = List.of("UnneededStrictfpWarning1.java:1:17: compiler.warn.strictfp",
|
||||
"UnneededStrictfpWarning1.java:10:10: compiler.warn.strictfp",
|
||||
"UnneededStrictfpWarning1.java:12:29: compiler.warn.strictfp",
|
||||
"UnneededStrictfpWarning1.java:16:28: compiler.warn.strictfp",
|
||||
"UnneededStrictfpWarning1.java:18:21: compiler.warn.strictfp",
|
||||
"5 warnings");
|
||||
checkLog(log, expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTopLevelSuppression(Path base) throws IOException {
|
||||
Path src = base.resolve("src");
|
||||
|
||||
tb.writeJavaFiles(src, UNNEEDED_STRICTFP_WARNING2_TOP_LEVEL_SUPPRESSION);
|
||||
Path classes = base.resolve("classes");
|
||||
tb.createDirectories(classes);
|
||||
|
||||
List<String> log;
|
||||
|
||||
// Warning implicitly enabled, no messages expected
|
||||
log = new JavacTask(tb)
|
||||
.options("-Werror")
|
||||
.outdir(classes)
|
||||
.files(tb.findJavaFiles(src))
|
||||
.run(Expect.SUCCESS)
|
||||
.writeAll()
|
||||
.getOutputLines(Task.OutputKind.DIRECT);
|
||||
checkEmptyLog(log);
|
||||
|
||||
// Warning explicitly enabled, no messages expected
|
||||
log = new JavacTask(tb)
|
||||
.options("-Xlint:strictfp", "-Werror")
|
||||
.outdir(classes)
|
||||
.files(tb.findJavaFiles(src))
|
||||
.run(Expect.SUCCESS)
|
||||
.writeAll()
|
||||
.getOutputLines(Task.OutputKind.DIRECT);
|
||||
checkEmptyLog(log);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInnerSuppression(Path base) throws IOException {
|
||||
Path src = base.resolve("src");
|
||||
|
||||
tb.writeJavaFiles(src, UNNEEDED_STRICTFP_WARNING3_INNER_SUPPRESSION);
|
||||
Path classes = base.resolve("classes");
|
||||
tb.createDirectories(classes);
|
||||
|
||||
// Warning enabled, 3 messages expected
|
||||
List<String> log = new JavacTask(tb)
|
||||
.options("-XDrawDiagnostics")
|
||||
.outdir(classes)
|
||||
.files(tb.findJavaFiles(src))
|
||||
.run(Expect.SUCCESS)
|
||||
.writeAll()
|
||||
.getOutputLines(Task.OutputKind.DIRECT);
|
||||
|
||||
var expected = List.of("UnneededStrictfpWarning3.java:1:17: compiler.warn.strictfp",
|
||||
"UnneededStrictfpWarning3.java:10:10: compiler.warn.strictfp",
|
||||
"UnneededStrictfpWarning3.java:17:28: compiler.warn.strictfp",
|
||||
"3 warnings");
|
||||
checkLog(log, expected);
|
||||
}
|
||||
|
||||
protected void runTests() throws Exception {
|
||||
runTests(m -> new Object[] { Paths.get(m.getName()).toAbsolutePath() });
|
||||
}
|
||||
|
||||
// If warnings are enabled, should generate 5 warnings for the 5
|
||||
// explicit uses of strictfp.
|
||||
private static final String UNNEEDED_STRICTFP_WARNING1_NO_SUPPRESSION =
|
||||
"""
|
||||
public strictfp class UnneededStrictfpWarning1 {
|
||||
// Implicit strictfp, no warning
|
||||
public UnneededStrictfpWarning1() {super();}
|
||||
|
||||
public static void main(String... args) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
strictfp interface StrictfpInterface {
|
||||
default double foo() {return 42.0;};
|
||||
default strictfp double bar() {return 21.0;};
|
||||
}
|
||||
|
||||
class StrictfpMethod {
|
||||
static strictfp double quux() {return 42.0;}
|
||||
|
||||
static strictfp class NestedStrictfpClass {}
|
||||
}
|
||||
""";
|
||||
|
||||
// If warnings are enabled, no warnings should be generated due to
|
||||
// suppression at the top-most level.
|
||||
private static final String UNNEEDED_STRICTFP_WARNING2_TOP_LEVEL_SUPPRESSION =
|
||||
"""
|
||||
@SuppressWarnings("strictfp")
|
||||
public strictfp class UnneededStrictfpWarning2 {
|
||||
// Implicit strictfp, no warning
|
||||
public UnneededStrictfpWarning2() {super();}
|
||||
|
||||
public static void main(String... args) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("strictfp")
|
||||
strictfp interface StrictfpInterface {
|
||||
default double foo() {return 42.0;};
|
||||
default strictfp double bar() {return 21.0;};
|
||||
}
|
||||
|
||||
@SuppressWarnings("strictfp")
|
||||
class StrictfpMethod {
|
||||
static strictfp double quux() {return 42.0;}
|
||||
|
||||
static strictfp class NestedStrictfpClass {}
|
||||
}
|
||||
""";
|
||||
|
||||
// If warnings are enabled, 3 warnings should be generated.
|
||||
private static final String UNNEEDED_STRICTFP_WARNING3_INNER_SUPPRESSION =
|
||||
"""
|
||||
public strictfp class UnneededStrictfpWarning3 {
|
||||
// Implicit strictfp, no warning
|
||||
public UnneededStrictfpWarning3() {super();}
|
||||
|
||||
public static void main(String... args) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
strictfp interface StrictfpInterface {
|
||||
default double foo() {return 42.0;};
|
||||
@SuppressWarnings("strictfp")
|
||||
default strictfp double bar() {return 21.0;};
|
||||
}
|
||||
|
||||
class StrictfpMethod {
|
||||
static strictfp double quux() {return 42.0;}
|
||||
|
||||
@SuppressWarnings("strictfp")
|
||||
static strictfp class NestedStrictfpClass {}
|
||||
}
|
||||
""";
|
||||
}
|
Loading…
Reference in New Issue
Block a user